合并2个数字列表并从最小到最大排序的功能?

时间:2015-07-28 06:26:45

标签: c++ arrays function sorting loops

我必须创建一个需要2个输入流和一个输出流的函数。该函数应该从2个单独的文件中读取整数列表,合并该列表,将数字从最小到最大排序,然后将这个合并和排序的列表输出到新文件中。

以下是该功能的代码:

void merge(ifstream& inStream1, ifstream& inStream2, ofstream& outStream)
{
    int arr[100], i = 0;

    while(!inStream1.eof())
    {
        inStream1>>arr[i++];
    }

    while(!inStream2.eof())
    {
        inStream2>>arr[i++];
    }

    int indexOfNextSmallest;
    for (int index = 0; index < i - 1; index++)
    {
        indexOfNextSmallest = indexOfSmallest(arr, index, i);
        swapValues(arr[index], arr[indexOfNextSmallest]);
    }

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

int indexOfSmallest(const int arr[], int startIndex, int i)
{
    int min = arr[startIndex], indexOfMin = startIndex;

    for (int index = startIndex + 1; index < i; index++)
    {
        min = arr[index];
        indexOfMin = index;
    }
    return indexOfMin;
}

void swapValues(int& v1, int& v2)
{
    int temp;
    temp = v1;
    v1 = v2;
    v2 = temp;
}

以下是输入输出示例:

文件1包含以下数字:

4
5
8
11
18
28 

文件2包含以下数字:

87
234
11
8
9
45
23

输出到新文件:

23
4
5
8
11
18
28
1988923808
87
234
11
8
9
45

我完全迷失了。请帮我解决这个问题。感谢。

1 个答案:

答案 0 :(得分:0)

int arr[100]

为什么呢?你知道两个文件中的元素总数不超过100个吗?可能不对,对吧?

因此,您最好使用可以动态调整其大小的数据结构,例如std::vector。但是,由于您似乎也想要删除重复项,因此std::set是更好的选择。这会给你另一个奖励:std::set的元素被排序。

这样,您的问题就会缩小为:

void merge(std::istream & in1, std::istream & in2, std::ostream & out) {
 // The set is used to store the elements from both files.
 // Since it also sorts them, no explicit sorting is needed.
 // Duplicates will be removed, if that's not what you want, use a multiset
 std::set<int> storage;
 // The istream_iterator applies operator>> to the whole file, effectively
 // reading the whole file contents.
 storage.insert(
   std::istream_iterator<int>(in1),
   std::istream_iterator<int>());
 storage.insert(
   std::istream_iterator<int>(in2),
   std::istream_iterator<int>());
 // We copy each element of the set (they're in sorted order) into
 // the output. Using the ostream_iterator, it's like writting
 // for (auto element : storage) { out << element << " "; }
 std::copy(
   std::begin(storage), std::end(storage),
   std::ostream_iterator<int>(out, " ")); // if you want seperate lines use "\n"
}

根据您的输入和此代码,我得到:

4 5 8 9 11 18 23 28 45 87 234 

使用标准库为您提供的内容!

关于您的代码:

int indexOfSmallest(const int arr[], int startIndex, int i)
{
    int min = arr[startIndex], indexOfMin = startIndex;

    for (int index = startIndex + 1; index < i; index++)
    {
        min = arr[index]; /* HERE */
        indexOfMin = index;
    }
    return indexOfMin;
}

你不看,当前元素(index)是否实际上小于当前最小值!

// inside that loop
if (arr[index] < min) {
 min = arr[index];
 indexOfMin = index;
}

(当然,还有std::min_element。)

哦,并且:

void merge(ifstream & //...

不具备您没有的硬编码要求。您不需要文件流,只需要流,因此istreamostream是更好的选择。

还有:

while(!inStream1.eof())
{
    inStream1>>arr[i++];
}

考虑包含文本字符串hello的文件。然后您的流将失败,但您继续读取输入。更好地直接测试输入操作:

while (inStream1 >> arr[i++]);