如何将值输入到已定义的数组中?

时间:2019-05-29 12:21:47

标签: c++ arrays for-loop

编写一个程序,该程序将10个给定的数字输出到两行中,其中一个表示奇数,另一个表示偶数。使用数组。

在声明了用户输入的10个数字的输入数组之后,我尝试声明了奇数和偶数值的单独数组,这些数组随后将通过for循环进行排序。

当我需要将这些值 n 分配给奇数或偶数数组时,我陷入困境。

int input[10];
int odd[]{};
int even[]{};
int n;

for(n=0;n<10;n++)
{
    if ((input[n])%2==0)
    {
      odd[n] = n; 
    }
    else
    {
      even[n] = n;
    }

4 个答案:

答案 0 :(得分:3)

您不需要为此进行动态分配。我们可以制作两个数组,并根据需要填充它们。

static constexpr std::size_t N = 10;
const int input[N] = { /* user input here */ };

int odd[N] = {};
int even[N] = {};

std::size_t countOdd = 0;
std::size_t countEven = 0;

for (std::size_t i = 0; i < N; i++)
{
    if (input[i] % 2 == 0)
       even[countEven++] = input[i];
    else
       odd[countOdd++] = input[i];
}

Nodd的末尾总共有even(10)个元素“浪费”了(分布不明),但是谁在乎呢?十个自动存储int秒!没什么。只要我们跟踪我们“关心”的几率和几率,一切都很好。

现在为两行输出:

for (std::size_t i = 0; i < countOdd; i++)
    std::cout << odd[i] << ' ';
std::cout << '\n';

for (std::size_t i = 0; i < countEven; i++)
    std::cout << even[i] << ' ';
std::cout << '\n';

容易!

我在适用于数组索引的地方使用了std::size_t,而不是int,但是如果您愿意,可以暂时忽略它。我还修复了您的模运算,并且您存储的是偶数/奇数值的索引,而不是值本身。


完整程序示例:

#include <iostream>
#include <cstddef>  // for std::size_t

int main()
{
    static constexpr std::size_t N = 10;
    const int input[N] = { 1,5,9,14,3,99,82,42,43,70};

    int odd[N] = {};
    int even[N] = {};

    std::size_t countOdd = 0;
    std::size_t countEven = 0;

    for (std::size_t i = 0; i < N; i++)
    {
        if (input[i] % 2 == 0)
           even[countEven++] = input[i];
        else
           odd[countOdd++] = input[i];
    }

    for (std::size_t i = 0; i < countOdd; i++)
        std::cout << odd[i] << ' ';
    std::cout << '\n';

    for (std::size_t i = 0; i < countEven; i++)
        std::cout << even[i] << ' ';
    std::cout << '\n';
}

// g++ -std=c++17 -O2 -Wall -pedantic -pthread main.cpp && ./a.out
// 1 5 9 3 99 43 
// 14 82 42 70 

live demo

答案 1 :(得分:2)

避免动态分配或任何其他存储的一个好技巧是对集合进行分区。这出现在快速排序等算法中,因此每个计算机科学家都应该学习它。

您要做的就是从两个索引或指针开始,一个向前或向后移动。只要项目在正确的分区中,就将指针移过它。一旦两个指针都在错误的分区中找到了元素,请交换它们并继续。指针收敛后,分区完成。

或者,如果您希望保持输入不变,则可以进行等于整个输入大小的单次分配,而无需重新分配或将已处理的项目移动到新的缓冲区。

答案 2 :(得分:1)

正如vahancho在评论中所说,odd[]even[]都是静态数组。这意味着创建后就无法更改其中任何一个的大小。此外,在声明数组时,大小不能为“动态”,即int odd[n];仅在n为编译时间常数时才有效(请注意,某些编译器将其作为扩展名提供,但不是标准c ++ )。

因此,这里有点卡住了,大多数人会考虑使用大小可变的常规std::vector。 不幸的是,您在问题中指定了“使用数组”。埃尔夫,回到第一广场。

让我们想一想,并记住数组可以看作是指针。在下图中,我们定义了一个数组arr[5]。然后arr是指向地址1000的指针,该地址是数组的第一个值:

剧透警报:您可以使用此属性创建动态数组。 好的,让我们为两个奇数和偶数数组定义一个指针,并声明它们的关联大小:

int * odd_array = NULL;
int * even_array = NULL;

int odd_array_size = 0, even_array_size = 0;

现在,我们的想法是在找到奇数或偶数时增加良数组的大小,并使用void* realloc(void* ptr, size_t size)提供的C函数<cstdlib>来增加分配给数组的大小。在您的情况下,您可能想在遍历input数组时这样做。这是您所拥有的示例:

for (int n = 0; n < 10; n++)
{
    if ((input_array[n]) % 2 != 0) // We find an odd number
    {
        odd_array_size++; // Increase the size of the array
        odd_array = (int*)realloc(odd_array, odd_array_size * sizeof(int)); // Reallocate more memory
        odd_array[odd_array_size-1] = input_array[n]; // Add the value in your new allocated memory
    }
    else
    {
        // Same here, but in the case of an even number
        even_array_size++;
        even_array = (int*)realloc(even_array, even_array_size * sizeof(int));
        even_array[even_array_size-1] = input_array[n];
    }
}

这样,您将得到两个数组odd_arrayeven_array,分别用input_array的奇数和偶数填充,这两个数组的大小分别为odd_array_sizeeven_array_size

这基本上是C的方法。您可能会考虑使用智能指针(以便安全地释放内存),如果允许,可以使用std::vectors,这是解决此问题的最佳方法。因此,如果您使用它,请不要忘记在程序末尾释放两个数组。

我希望这会有所帮助和明确,如有需要,请随时在评论中要求我澄清。

答案 3 :(得分:0)

您需要为D:\Apps\Pojazdy\platforms\android\app\src\main\java\org\apache\cordova\firebase\FirebasePluginInstanceIDService.java:6: error: cannot find symbol import com.google.firebase.iid.FirebaseInstanceIdService; ^ symbol: class FirebaseInstanceIdService location: package com.google.firebase.iid D:\Apps\Pojazdy\platforms\android\app\src\main\java\org\apache\cordova\firebase\FirebasePluginInstanceIDService.java:8: error: cannot find symbol public class FirebasePluginInstanceIDService extends FirebaseInstanceIdService { ^ symbol: class FirebaseInstanceIdService D:\Apps\Pojazdy\platforms\android\app\src\main\java\org\apache\cordova\firebase\FirebasePlugin.java:610: error: method getByteArray in class FirebaseRemoteConfig cannot be applied to given types; : FirebaseRemoteConfig.getInstance().getByteArray(key, namespace); ^ required: String found: String,String reason: actual and formal argument lists differ in length D:\Apps\Pojazdy\platforms\android\app\src\main\java\org\apache\cordova\firebase\FirebasePlugin.java:629: error: method getValue in class FirebaseRemoteConfig cannot be applied to given types; : FirebaseRemoteConfig.getInstance().getValue(key, namespace); required: String found: String,String reason: actual and formal argument lists differ in length D:\Apps\Pojazdy\platforms\android\app\src\main\java\org\apache\cordova\firebase\FirebasePlugin.java:686: error: no suitable method found for setDefaults(Map<String,Object>,String) FirebaseRemoteConfig.getInstance().setDefaults(defaultsToMap(defaults), namespace); ^ method FirebaseRemoteConfig.setDefaults(Map<String,Object>) is not applicable (actual and formal argument lists differ in length) method FirebaseRemoteConfig.setDefaults(int) is not applicable (actual and formal argument lists differ in length) D:\Apps\Pojazdy\platforms\android\app\src\main\java\org\apache\cordova\firebase\FirebasePlugin.java:885: error: cannot find symbol myTrace.incrementCounter(counterNamed); ^ symbol: method incrementCounter(String) location: variable myTrace of type Trace D:\Apps\Pojazdy\platforms\android\app\src\main\java\org\apache\cordova\firebase\FirebasePluginInstanceIDService.java:17: error: method does not override or implement a method from a supertype @Override ^ Note: Some input files use or override a deprecated API. Note: Recompile with -Xlint:deprecation for details. Note: D:\Apps\Pojazdy\platforms\android\app\src\main\java\by\chemerisuk\cordova\support\ReflectiveCordovaPlugin.java uses unchecked or unsafe operations. Note: Recompile with -Xlint:unchecked for details. 7 errors FAILURE: Build failed with an exception. * What went wrong: Execution failed for task ':app:compileDebugJavaWithJavac'. odd创建一个动态数组。
您还犯了一个错误,如果模数等于零,则数字是偶数而不是奇数。并且您要添加even而不是input[n]

我认为您应该使用STL容器而不是原始数组,这样会更容易。

您可以执行以下操作:

n

您可以将三元条件运算符std::array<int, 10> input {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; // fill the array with anything you want std::vector<int> odd, even; for(unsigned int n = 0; n < input.size(); ++n) { (input[n]%2) ? (odd.push_back(input[n])) : (even.push_back(input[n])); } 替换为:

condition ? action_if_true : action_if_false

我希望它能提供帮助。