1. ホーム
  2. c++

[解決済み] 配列要素のシフト

2022-02-04 21:31:05

質問

この質問は以前にもされたことがあるのですが、理解できず、解決できないので、助けてほしいのです。私は自分の配列の要素を左の位置に移動させる必要があります。入力が 1,2,3,4,5 であれば、出力は 2,3,4,5,1 になります。私は右側に同じことをしましたが、左側に私はそれを理解することはできません、また、ロジックを説明してください、ありがとうございます。

    #include <iostream>
    using namespace std;
    int a[100],n,i,tempr,templ;
    int main()
    {
    cin>>n;
    for(i=1;i<=n;i++) cin >> a[i];
    for(i=1;i<=n;i++)
        {
            tempr = a[n];
            a[n] = a[i];
            a[i] = tempr;
            cout<<"Right: "<<a[i]<<endl;
        }
    for(i=1;i<=n;i++)
        {
            templ = a[2];
            a[2] = a[i];
            a[i] = templ;
            cout<<"Left: "<<a[i]<<endl;
        }
    return 0;
}

助けてください

解決方法は?

最初の問題は、インデックス作成がうまくいかないことです。

for(i=1;i<=n;i++) cin >> a[i]; //wrong logic, C++ indexing start from 0

正しいアプローチ

for(i=0;i<n;i++) //all your loops

2つ目の問題は、要素をシフトさせるロジックが誤っていることです。 修正版です。

//input example: 1 2 3 4 5
//to the left
int temp = a[0]; //remember first element
for(i=0;i<n-1;i++)
{
    a[i] = a[i+1]; //move all element to the left except first one
}
a[n-1] = temp; //assign remembered value to last element
//output: 2 3 4 5 1
cout << "To left: " << endl;
for(i=0;i<n;i++)
    cout << a[i] << endl;

//to the right
temp = a[n-1]; //remember last element
for(i=n-1;i>=0;i--)
{
    a[i+1] = a[i]; //move all element to the right except last one
}
a[0] = temp; //assign remembered value to first element
//output: 1 2 3 4 5 because elements are shifted back by right shift
cout << "To right: " << endl;
for(i=0;i<n;i++)
    cout << a[i] << endl;


EDIT。

両シフトを表示する方法。

#include <iostream>
    using namespace std;
    int to_left[5], to_right[5],n,i,tempr,templ;
    int main()
    {

    cout << "Input array size: ";
    cin >> n;

    for(i=0;i<n;i++)
    {
        cin >> to_left[i]; //read values to first array
        to_right[i]=to_left[i]; //then copy values to second one
    }

    //shift first array to left
    int temp = to_left[0]; 
    for(i=0;i<n-1;i++)
    {
        to_left[i] = to_left[i+1]; //move all element to the left except first one
    }
    to_left[n-1] = temp; //assign remembered value to last element
    //output: 2 3 4 5 1
    cout << "To left: " << endl;
    for(i=0;i<n;i++)
        cout << to_left[i] << endl;

    //shift second array to right
    temp = to_right[n-1]; //remember last element
    for(i=n-1;i>=0;i--)
    {
        to_right[i+1] = to_right[i]; //move all element to the right except last one
    }
    to_right[0] = temp; //assign remembered value to first element
    //output: 1 2 3 4 5 because elements are shifted back by right shift
    cout << "To right: " << endl;
    for(i=0;i<n;i++)
        cout << to_right[i] << endl;

    return 0;
}

あなたのコードはC言語のコードに非常によく似ていることに注意してください。C++では、変数の宣言は冒頭だけでなく、コードのどのセグメントでも行うことができます。C++では、変数の宣言は for のようなループになります。 for(int i=0; i<...) - グローバル変数が不要 i

参考までに、あなたが直面している問題を満足させる良いC++のコード例を挙げておきます。

#include <iostream>
#include <vector>
int main()
{   
    std::size_t n; //size_t is unsiged type used for various sizes of containers or types
    std::cout << "Input array size: ";
    std::cin >> n;

    std::vector<int> to_left(n), to_right(n); //two dynamic arrays containing integers, takin n as their size

    for(std::size_t i=0;i<to_left.size();++i) //use vector size(), instead of n, also ++i in considered better for loops that i++ (may be faster)
    {
        std::cin >> to_left[i];
        to_right[i]=to_left[i];
    }

    int temp = to_left[0]; //declare temp here, not at the begining of code
    for(std::size_t i=0;i<n-1;++i)
        to_left[i] = to_left[i+1];
    to_left[n-1] = temp;

    std::cout << "To left: " << std::endl;
    for(std::size_t i=0;i<n;++i)
        std::cout << to_left[i] << std::endl;

    temp = to_right[n-1]; //reuse temp
    for(int i=to_right.size()-1;i>=0;--i) //note int, not std::size_t, because size_t is always >=0, loop would never end.
        to_right[i+1] = to_right[i];
    to_right[0] = temp;

    std::cout << "To right: " << std::endl;
    for(std::size_t i=0;i<n;i++)
        std::cout << to_right[i] << std::endl;

    return 0;
}

そして、これが理想的なC++のコードになります。

#include <iostream>
#include <vector>
#include <algorithm>
int main()
{   
    std::size_t n;
    std::cout << "Input array size: ";
    std::cin >> n;

    std::vector<int> to_left(n), to_right(n);

    for(std::size_t i=0;i<to_left.size();++i)
    {
        std::cin >> to_left[i];
        to_right[i]=to_left[i];
    }

    // rotate first array to the left
    std::rotate(to_left.begin(), to_left.begin() + 1, to_left.end());

    // rotate second array to right
    std::rotate(to_right.rbegin(), to_right.rbegin() + 1, to_right.rend());

    std::cout << "To left:" << std::endl;
    for(auto x : to_left) //C++11 feature, x iterates through container
        std::cout << x << std::endl;

    std::cout << "To right:" << std::endl;
    for(auto x : to_right)
        std::cout << x << std::endl;

    return 0;
}