首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

C 語言陣列循環右移:題目需求分析與正確實作完整指南

     編輯:程式設計綜合問答

題目重述

有 n 個整數(0 < n ≤ 20),將其順序向後移動 m 位置(m < n),最後 m 個數移到最前面。

範例:

輸入:8 3 1 2 3 4 5 6 7 8
輸出:6 7 8 1 2 3 4 5

原代碼問題分析

原代碼存在多處嚴重邏輯錯誤:

  • scanf("%d", a) 缺少 & 且僅讀取單一整數,非陣列
  • 缺少迴圈讀取 n 個數字
  • 索引計算 a[n-i]、a[j] 邏輯混亂,會越界
  • if(n20) 缺少運算子,應為 if(n > 20)
  • 整體演算法思路未建立

正確演算法思路:三步反轉法(O(1) 空間,O(n) 時間)

將陣列視為兩段:[0, n-m-1] 和 [n-m, n-1]。目標交換兩段順序。

  1. 整體反轉:reverse(0, n-1)
  2. 反轉前 m 個:reverse(0, m-1)
  3. 反轉後 n-m 個:reverse(m, n-1)

範例演示: 1 2 3 4 5 6 7 8, m=3

整體反轉:8 7 6 5 4 3 2 1
反轉前3:6 7 8 5 4 3 2 1
反轉後5:6 7 8 1 2 3 4 5  ✓

完整正確代碼

#include <stdio.h>

void reverse(int arr[], int left, int right) {
    while (left < right) {
        int temp = arr[left];
        arr[left] = arr[right];
        arr[right] = temp;
        left++;
        right--;
    }
}

int main() {
    int n, m;
    int a[20];

    printf("輸入總數 n (1-20): ");
    scanf("%d", &n);
    if (n < 1 || n > 20) { printf("錯誤:n 超出範圍\n"); return 1; }

    printf("輸入後移位數 m (0-%d): ", n-1);
    scanf("%d", &m);
    if (m < 0 || m >= n) { printf("錯誤:m 超出範圍\n"); return 1; }

    printf("輸入 %d 個整數: ", n);
    for (int i = 0; i < n; i++) {
        scanf("%d", &a[i]);
    }

    // 三步反轉法
    reverse(a, 0, n - 1);
    reverse(a, 0, m - 1);
    reverse(a, m, n - 1);

    printf("移動後的數列: ");
    for (int i = 0; i < n; i++) {
        printf("%d ", a[i]);
    }
    printf("\n");

    return 0;
}

替代方案:額外陣列法(易理解,O(n) 空間)

int b[20];
for (int i = 0; i < n; i++) {
    b[(i + m) % n] = a[i];  // 計算新位置
}
// 複製回 a 或直接輸出 b

關鍵測試案例

輸入預期輸出說明
5 0
1 2 3 4 5
1 2 3 4 5m=0 不移動
5 4
1 2 3 4 5
2 3 4 5 1m=n-1 最大移動
1 0
99
99單元素邊界

總結

陣列循環移位是經典演算法題。三步反轉法空間效率最佳,適合嵌入式/面試場合;額外陣列法直觀易寫,適合一般應用。關鍵在於:正確讀取輸入、邊界檢查、索引計算無誤。建議新手先掌握額外陣列法理解核心邏輯,再學習原地反轉優化。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved