Как изменить этот простой код, чтобы избежать дублирования кода? - PullRequest
2 голосов
/ 29 июля 2011

Я решаю следующую простую задачу (на одном из сайтов 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;

Я сказал тому голосу внутри себя, что, возможно, можно было бы избежать печати отдельно в конце. Он сказал мне, что тогда, возможно, будет слишком много if и else для такой простой проблемы. Теперь я не хочу сделать код короче . Я также не хочу минимизировать количество if и else. Но я делаю хочу избавиться от специальной печати в конце цикла, не усложняя код.

Я действительно считаю, что эту простую проблему можно решить с помощью более простого кода, чем мой. Надеюсь, я был ясен, и вопрос не будет считаться неконструктивным:)

Заранее спасибо.

Ответы [ 5 ]

2 голосов
/ 30 июля 2011

Моя версия: вместо этого читаем первое значение как особый случай.

#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 голосов
/ 29 июля 2011

Я придумал это. нет дублирования кода, но немного менее читабельно Использование вектора только для удобства тестирования

РЕДАКТИРОВАТЬ мой ответ предполагает, что вы знаете числа заранее и не обрабатываете их на лету

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;
}
0 голосов
/ 29 июля 2011

Я думаю, что это сработает:

#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, но я хотел остаться как можно ближе к оригиналу.

0 голосов
/ 29 июля 2011

немного больше CREATIVE ответ, этот не делает предположения о том, что входные данные все известны до начала цикла.Это печатает итог каждый раз, но использует возврат каретки, а не перевод строки.Новая строка вставляется при обнаружении другого номера.

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;

0 голосов
/ 29 июля 2011

Запустите ваш цикл на один дольше (> = 0 вместо> 0), и в последнем раунде вместо чтения currentNumber из cin выполните currentNumber = lastNumber + 1 (чтобы он гарантированно отличался).

...