Подсчитать количество цифр в массиве (c ++) - PullRequest
0 голосов
/ 09 апреля 2020

Допустим, у меня есть массив arr [5] = {5,2,3,2,5}, и я написал для него следующую программу

#include <iostream>
using namespace std;
int main()
{
  int n;
  cout<<"Enter Length of Elements= ";
  cin>>n;
  int arr[50];
  for(int i=0;i<n;i++)
  {
      cout<<"Enter Number=";
      cin>>arr[i];
  }
  for(int i=0;i<n;i++)
  {
      int countNum=1;


      for(int j=i+1;j<n;j++)
      {
          if(arr[i]==arr[j])
          {
              if(i>0)
              {
                  int countNum2=0;


                  for(int k=0;k>i;k++)
                  {
                      //bool repeat=false;

                      if(arr[i]==arr[k])
                      {
                        //repeat=false;
                      }
                      else
                      {
                          countNum2++;
                      }
                  }
                  if(countNum2==i)
                  {
                     countNum++;
                  }
              }
              else
              {
                countNum++;
              }
          }
          else
          {
              for(int k=0;k<i;k++)
              {
                  if(arr[k]==arr[i])
                  {

                  }
                  else
                  {
                      countNum=1;
                  }

              }
          }

      }
      cout<<arr[i]<<" has appeared "<<countNum<< "Times"<<endl;

  }

    return 0;
}

, но почему я получаю 5, я появился 2 Раз

2 появилось 1 Время

3 появилось 1 Время

2 появилось 1 Время

5 появилось 1 Время

вместо

5 появилось 2 раза

2 появилось 2 раза

3 появилось 1 раз

так как исправить справку моей программы!

Ответы [ 2 ]

2 голосов
/ 09 апреля 2020

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

Также использование такого количества циклов совершенно не нужно .

Вам просто нужно реализовать два цикла: внешний, проходящий через все элементы, и внутренний, сначала проверяющий на наличие дубликатов (с помощью массива для проверки состояния частоты / появления), и подсчет внешнего вида каждого элемента отдельно с помощью переменная, используемая в качестве счетчика.

Установите массив счетчиков (с соответствующим размером вашего взятого массива) с указанным значением c (скажем, ноль) и измените это значение, когда тот же элемент возникает во время обхода массива, чтобы снова не считать это значение.

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

С небольшими изменениями ваш код будет работать так, как вы хотите:

#include <iostream>
using namespace std;
int main()
{
  int n;
  cout<<"Enter Length of Elements = ";
  cin>>n;
  int arr[50];
  for(int i=0;i<n;i++)
  {
      cout<<"Enter Number = ";
      cin>>arr[i];
  }

  int counter[50];
  for(int i=0; i<n; i++)
    counter[i]=0;

    // Our counter variable, but counts will be transferred to count[] later on:
    int tempcount;

    for(int i=0; i<n; i++)
    {   // Each distinct element occurs once atleast so initialize to one:
        tempcount = 1;
        for(int j=i+1; j<n; j++)
        {
            // If dupe is found: 
            if(arr[i]==arr[j])
            {
                tempcount++;

                // Ensuring not to count frequency of same element again:
                counter[j] = 1;
            }
        }

        // If occurence of current element is not counted before:
        if(counter[i] != 1)
            counter[i] = tempcount;
    }

    for(int i=0; i<n; i++)
    {
        if(counter[i] != 0)
            printf("%d has appeared %d times.\n", arr[i], counter[i]);
    }
 return 0;
}

Я использовал переменную tempcount подсчитать вхождение каждого элемента и инициализированного нулями массива count, чтобы проверить дуплицы (установив его в 1 для дублирующейся записи и не считая его, если он квалифицируется как 1) первым. Затем я перенес подсчитанные значения вхождения в counter[] с tempcount на каждой внешней итерации l oop. (для всех уникальных элементов)

1 голос
/ 09 апреля 2020

Это именно то, что вам нужно (количество каждого числа в массиве):

// we'll store amounts of numbers like key-value pairs.
// std::map does exactly what we need. As a key we will
// store a number and as a key - corresponding counter
std::map<int, size_t> digit_count;

// it is simpler for explanation to have our
// array on stack, because it helps us not to
// think about some language-specific things
// like memory management and focus on the algorithm
const int arr[] = { 5, 2, 3, 2, 5 };

// iterate over each element in array
for(const auto elem : arr) 
{
    // operator[] of std::map creates default-initialized
    // element at the first access. For size_t it is 0.
    // So we can just add 1 at each appearance of the number 
    // in array to its counter.
    digit_count[elem] += 1;
}

// Now just iterate over all elements in our container and
// print result. std::map's iterator is a pair, which first element
// is a key (our number in array) and second element is a value
// (corresponding counter)
for(const auto& elem : digit_count) {
    std::cout << elem.first << " appeared " << elem.second << " times\n";
}

https://godbolt.org/z/_WTvAm

Хорошо, давайте напишем некоторые основы c код, но сначала давайте рассмотрим алгоритм (он не самый эффективный, но более понятный):

Самый понятный способ - перебирать каждое число в массиве и увеличивать некоторый соответствующий счетчик на единицу. Пусть это будет пара с первым элементом, который будет нашим номером, а вторым - счетчиком:

struct pair {
    int number;
    int counter;
};

Другая часть алгоритма будет объяснена в коде ниже

// Say that we know an array length and its elements
size_t length = // user-defined, typed by user, etc.
int* arr = new int[length];
// input elements

// There will be no more, than length different numbers
pair* counts = new pair[length];

// Initialize counters
// Each counte will be initialized to zero explicitly (but it is not obligatory,
// because in struct each field is initialized by it's default
// value implicitly)
for(size_t i = 0; i < length; i++) {
    counts[i].counter = 0;
}

// Iterate over each element in array: arr[i]
for(size_t i = 0; i < length; i++)
{
    // Now we need to find corresponding counter in our counters.
    size_t index_of_counter = 0;

    // Corresponding counter is the first counter with 0 value (in case when
    // we meet current number for the first time) or the counter that have
    // the corresponding value equal to arr[i]
    for(; counts[index_of_counter].counter != 0 && counts[index_of_counter].number != arr[i]; index_of_counter++)
        ; // Do nothing here - index_of_counter is incrementing in loop-statement

    // We found an index of our counter
    // Let's assign the value (it will assign a value
    // to newly initialized pair and won't change anything
    // in case of already existing value).
    counts[index_of_counter].number = arr[i];

    // Increment our counter. It'll became 1 in case of new
    // counter, because of zero assigned to it a bit above.
    counts[index_of_counter].counter += 1;
}

// Now let's iterate over all counters until we reach the first
// containing zero (it means that this counter and all after it are not used)
for(size_t i = 0; i < length && counts[i].counter > 0; i++) {
    std::cout << counts[i].number << " appeared " << counts[i].counter << " times\n";
}

// correctly delete dynamically allocated memory
delete[] counts;
delete[] arr;

https://godbolt.org/z/hN33Pn

Более того, это точно такое же решение, как и с std::map (та же идея), поэтому я надеюсь, что оно поможет вам понять, как работает первое решение внутри

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...