如何重构这个简单的代码以避免代码重复?

时间:2011-07-29 14:55:29

标签: c++ code-organization

我正在解决以下简单问题(在俄罗斯的OnlineJugde网站之一,所以我不会在这里给出一个链接:)。通过示例比定义更容易说明问题。

输入:

10 // this is N, the number of the integers to follow
1 1 1 2 2 3 3 1 4 4

输出:

3 times 1.
2 times 2.
2 times 3.
1 times 1.
2 times 4.    

约束: 输入中的所有数字(包括 N )都是小于 10000 的正整数。

以下是我获得 接受 的代码:

#include <iostream>
using namespace std;

int main()
{
   int n; 
   cin >> n;
   int prevNumber = -1;
   int currentCount = 0;
   int currentNumber;
   while(n --> 0)  // do n times
   {
      cin >> currentNumber;
      if(currentNumber != prevNumber)
      {
         if(currentCount != 0) //we don't print this first time
         {
            cout << currentCount << " times " << prevNumber << "." << endl;
         }
         prevNumber = currentNumber;
         currentCount = 1;
      }
      else //if(currentNumber == prevNumber)
      {
         ++currentCount;
      }
   }
   cout << currentCount << " times " << prevNumber << "." << endl;
}

现在这是我的问题。我内心的一个小声音一直在告诉我,我正在做这两行:

cout << currentCount << " times " << prevNumber << "." << endl;

我告诉我内心的声音,最终可能会避免分开打印。它告诉我,对于这样一个简单的问题,可能会有太多ifelse。现在,我 想要使代码 更短 。我也不想最小化ifelse的数量。 但我想要在循环结束时摆脱特殊打印而不会使代码更复杂。

我真的相信这个简单的问题可以用比我更简单的代码来解决。希望我很清楚,这个问题不会被视为没有建设性。)

提前致谢。

5 个答案:

答案 0 :(得分:2)

我想出了这个。没有代码重复,但可读性稍差。使用vector只是为了方便测试

编辑我的回答是假设你提前知道这些数字而不是动态处理它们

vector<int> numbers;
numbers.push_back(1);
numbers.push_back(1);
numbers.push_back(1);
numbers.push_back(2);
numbers.push_back(2);
numbers.push_back(3);
numbers.push_back(3);
numbers.push_back(1);
numbers.push_back(4);
numbers.push_back(4);


for (int i=0; i<numbers.size(); i++)
{
    int count = 1;
    for (int j=i+1; j<numbers.size() && numbers[i] == numbers[j]; i++, j++)
    {
        count++;
    }
    cout << count << " times " << numbers[i] << "." << endl;
}

答案 1 :(得分:2)

我的版本:改为将第一个值作为特殊情况读取。

#include <iostream>

int main()
{
    int n;
    std::cin >> n;
    int value;
    std::cin >> value;
    --n;

    while (n >= 0) {
        int count = 1;
        int previous = value;
        while (n --> 0 && std::cin >> value && value == previous) {
            ++count;
        }
        std::cout << count << " times " << previous << ".\n";
    }
}

答案 2 :(得分:0)

再运行你的循环(&gt; = 0而不是&gt; 0),并且在最后一轮中,不是从cin读取currentNumber,而是执行currentNumber = lastNumber + 1(这样它保证不同)。

答案 3 :(得分:0)

略多 CREATIVE 回答,这个没有假设输入在循环开始之前全部已知。这会每次打印总计,但会使用\ r \ n回车但不使用换行符。检测到不同的数字时会插入新行。

int prev_number = -1;
int current_number;
int count = 0;
for (int i=0; i<numbers.size(); i++)
{
    current_number = numbers[i];
    if (current_number != prev_number)
    {
        count = 0;
        cout << endl;
    }
    count++;
    prev_number = current_number;
    cout << count  << " times " << numbers[i] << "." << "\r";
}

唯一的问题是光标留在最后一行。您可能需要附加cout << endl;

答案 4 :(得分:0)

我认为这会奏效:

#include <iostream>
using namespace std;

int main()
{
   int n; 
   cin >> n;
   int prevNumber = -1;
   int currentCount = 0;
   int currentNumber;

   int i = 0;
   while(i <= n)
   {
      if(i != n) cin >> currentNumber;

      if(currentNumber != prevNumber || i == n)
      {
         if(currentCount != 0)
         {
            cout << currentCount << " times " << prevNumber << "." << endl;
         }

         prevNumber = currentNumber;
         currentCount = 1;
      }
      else
      {
         ++currentCount;
      }   
      i++;
   }
}

我会使用for循环,但我希望保持尽可能接近原始。