У меня есть код, который меняет порядок массивов на основе индекса. Код работает нормально, когда он настроен для добавления чисел через редактор, но как мне переключить это, чтобы пользователь мог вводить числа как для массива, так и для индекса через терминал?

#include <iostream>

using namespace std;

void reorder(int arr[], int index[], int n)
{
    int temp[n];

    for (int i = 0; i < n; i++)
        temp[index[i]] = arr[i];

    for (int i = 0; i < n; i++) {
        arr[i] = temp[i];
        index[i] = i;
    }
}

int main()
{
    int arr[] = { 3, 2, 1, 5, 6, 4 };
    int arb[] = { 5, 6, 1, 3, 2, 4 };
    int index[] = { 3, 4, 2, 0, 1, 5 };

    int n = sizeof(arr) / sizeof(arr[0]);
    cout << "\nSequence array is: \n";
    for (int i = 0; i < n; i++)
        std::cout << index[i] << ' ';
    cout << "\nOriginal array is: \n";
    for (int i = 0; i < n; i++)
        cout << arr[i] << " ";
    printf("\n");

    reorder(arr, index, n);
    reorder(arb, index, n);

    cout << "Reordered array is: \n";
    for (int i = 0; i < n; i++)
        cout << arr[i] << " ";

    printf("\n");

    printf("\n");

    return 0;
}
c++
0
Ryuk 15 Окт 2019 в 17:32
1
std::cin >> ..?
 – 
Jarod42
15 Окт 2019 в 17:35
std::cin >> variable ...
 – 
Rietty
15 Окт 2019 в 17:35
Пожалуйста, отформатируйте свой код, прежде чем размещать его здесь. Вы можете использовать format.krzaq.cc
 – 
Thomas Sablik
15 Окт 2019 в 17:37
1
int temp[n]; - это массив переменной длины, который не допускается в ISO C ++. Вместо этого вы можете использовать std :: vector, размер глобального массива констант времени компиляции или динамическое распределение памяти.
 – 
Thomas Sablik
15 Окт 2019 в 17:40
2
Код работает нормально - Верно?. Он не может быть скомпилирован из-за того, что вы используете синтаксис, отличный от C ++.
 – 
PaulMcKenzie
15 Окт 2019 в 17:45

4 ответа

Взгляните на свою функцию reorder. Как PaulMcKenzie прокомментировал, код работает (если поправить, возможно, вот так):

void reorder(int arr[], int index[], int n)
{
    vector<int> temp(n);

    for (int i = 0; i < n; i++)
        temp[index[i]] = arr[i];

    for (int i = 0; i < n; i++) {
        arr[i] = temp[i];
        index[i] = i;
    }
}

См. живую демонстрацию.

Объяснение: массивы переменной длины не входят ни в один из стандартов C ++. Вы можете использовать для своих целей вектор, который инициализируется значениями n по умолчанию int (т. Е. 0). Это необходимо для произвольного доступа к нему. Конечно, ваше решение несколько слабое / ограниченное, потому что вы должны убедиться, что значения в index находятся в диапазоне: (0 <= v) && (v < NELEMS(arr)).

0
Wolf 15 Окт 2019 в 18:06

Как упоминал Томас выше, используйте вместо этого std :: vector. Однако, если вы действительно хотите использовать int [], следующее должно работать.

int nDigits = 0;
cout << "Enter number of digits:" << endl;
cin >> nDigits;

int* arr;
int* index;
arr  = new int[nDigits];
index = new int[nDigits];

for(int i = 0; i < nDigits; i++){
    cout << "Enter arr element (" << i << "):" << endl;
    cin >> arr[i];
    cout << "Enter index element (" << i << "):" << endl;
    cin >> index[i];
}

... Используйте векторы вместо tbh

0
Scheir 15 Окт 2019 в 18:11

У вас проблема с массивами переменной длины. Самое простое, но действительно плохое решение - использовать глобальную константу времени компиляции для размера массива. Вы можете использовать std::cin для чтения значений из терминала. Кстати, нельзя смешивать std::cout и std::printf. Используйте std::cout.

Вы должны добавить проверку пользовательского ввода, если каждая запись уникальна и находится в диапазоне [0, n-1].

#include <iostream>

using namespace std;

constexpr unsigned int n = 6;

void reorder(int arr[], int index[])
{
    int temp[n];

    for (int i = 0; i < n; i++)
        temp[index[i]] = arr[i];

    for (int i = 0; i < n; i++) {
        arr[i] = temp[i];
        index[i] = i;
    }
}

int main()
{
    int arr[] = { 3, 2, 1, 5, 6, 4 };
    int arb[] = { 5, 6, 1, 3, 2, 4 };
    int index[n];

    std::cout << "Enter " << n << " values: ";
    for (auto &element : index) {
        std::cin >> element;
    }

    cout << "\nSequence array is: \n";
    for (int i = 0; i < n; i++)
        std::cout << index[i] << ' ';
    cout << "\nOriginal array is: \n";
    for (int i = 0; i < n; i++)
        cout << arr[i] << " ";
    printf("\n");

    reorder(arr, index);
    reorder(arb, index);

    cout << "Reordered array is: \n";
    for (int i = 0; i < n; i++)
        cout << arr[i] << " ";

    printf("\n");

    printf("\n");

    return 0;
}

Лучшее решение - использовать std :: vector

#include <iostream>

using namespace std;


void reorder(std::vector<int> arr, std::vector<int> index)
{
    auto n = arr.size();
    std::vector<int> temp(n);

    for (int i = 0; i < n; i++)
        temp[index[i]] = arr[i];

    for (int i = 0; i < n; i++) {
        arr[i] = temp[i];
        index[i] = i;
    }
}

int main()
{
    std::vector<int> arr = { 3, 2, 1, 5, 6, 4 };
    std::vector<int> arb = { 5, 6, 1, 3, 2, 4 };
    auto n = arr.size();
    std::vector<int> index(n);

    std::cout << "Enter " << n << " values: ";
    for (auto &element : index) {
        std::cin >> element;
    }

    cout << "\nSequence array is: \n";
    for (int i = 0; i < n; i++)
        std::cout << index[i] << ' ';
    cout << "\nOriginal array is: \n";
    for (int i = 0; i < n; i++)
        cout << arr[i] << " ";
    printf("\n");

    reorder(arr, index);
    reorder(arb, index);

    cout << "Reordered array is: \n";
    for (int i = 0; i < n; i++)
        cout << arr[i] << " ";

    printf("\n");

    printf("\n");

    return 0;
}
0
Thomas Sablik 15 Окт 2019 в 18:19
Я думаю, что введение глобальной константы с именем n может быть быстрым, но это действительно плохой совет.
 – 
Wolf
15 Окт 2019 в 18:07
Хорошо, я изменил «не лучший» на «очень плохой». Также есть альтернативное решение.
 – 
Thomas Sablik
15 Окт 2019 в 18:09
Ваше векторное решение выглядит неплохо, но в случае предоставления разумного решения также переключитесь с printf на std::cout
 – 
Wolf
15 Окт 2019 в 18:09
Раньше я обычно модернизировал код в своих ответах и ​​получал за это отрицательные комментарии и голоса против. Сейчас только исправляю проблемы и иногда комментирую, как это можно модернизировать.
 – 
Thomas Sablik
15 Окт 2019 в 18:12
Хорошо, я вижу. Может быть, мы (лучше вас?) Должны добавить проверку диапазона к пользовательскому вводу, хранящемуся в index перед вызовом reorder. По крайней мере, это следует предложить.
 – 
Wolf
15 Окт 2019 в 18:15

Чтобы получить ввод из командной строки, используйте cin. Вам также нужно будет использовать вектор вместо массива для хранения «динамического массива», то есть массива, размер которого вы не знаете во время компиляции.

Лучше всего поместить этот ввод в строку и проанализировать эту строку, поскольку cin не обрабатывает неправильный ввод (для этого укажите строку).

string input;
cin >> input;

Затем вам нужно разделить ввод - проще всего, если разделителем будет пробел, для запятой вам понадобится другой метод (для этого вам нужно будет включить итератор, вектор и sstream)

istringstream iss(input);
vector<string> splitted_input{istream_iterator<string>(iss), istream_iterator<string>()};

И преобразовать его в числа (включить алгоритм для этого)

vector<int> parsed_input(splitted_input.size());
transform(splitted_input.begin(), splitted_input.end(), parsed_input.begin(), [](auto val){ return stoi(val);});

В качестве альтернативы вы можете использовать stoi напрямую без среднего шага разделения строки:

size_t idx = 0, input_len = input.size();
vector<int> values;
while (idx < input_len) {   
    size_t new_idx;
    values.push_back(stoi(input.substr(idx, input_len - idx), &new_idx));
    idx += new_idx;
    for(; !isdigit(input[idx]) && input[idx] != '-'; ++idx);  // skip to the next number
}
0
feature_engineer 15 Окт 2019 в 18:28