【问题标题】:Count Number of Digits in an array (c++)计算数组中的位数(c ++)
【发布时间】:2020-04-09 11:44:57
【问题描述】:

假设我有一个数组 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 次​​p>

2 出现了 1 次

3 出现了 1 次

2 出现了 1 次

5 出现了 1 次

而不是

5 出现了 2 次​​p>

2 出现了 2 次​​p>

3 出现了 1 次

那么如何修复我的程序 帮忙!

【问题讨论】:

  • 位数或只是一个数字的计数?
  • “为什么我得到 5 已经出现了两次” - 你是什么意思?这不是预期的输出还是你的意思是2?使用这么多循环也是完全没有必要的。
  • 你想要数组中每个唯一数字的计数吗?
  • 我不想一遍又一遍地打印那些已经打印出来的数字
  • 这正是“独特”的意思。

标签: c++ arrays for-loop if-statement


【解决方案1】:

您的代码的问题在于您没有删除重复项或分配一个有效存储数组中每个唯一元素的计数的数组。

另外,使用这么多循环是完全没有必要的。

您只需要实现两个循环,外部循环遍历所有元素,内部循环首先检查是否存在重复(使用数组来检查频率/出现状态),并使用用作变量的变量分别计算每个元素的出现次数计数器。

使用特定值(例如零)设置一个计数器数组(具有所取数组的相应大小),并在遍历数组时发生相同元素时更改该值,以触发不再计算该值。

然后每次内部循环完成对整个数组的迭代时,将计数值从计数器变量传输到计数器数组(我们设置并区分重复项的数组)。 (即在计算值之后放置)

稍作修改,您的代码将按照您的意愿运行:

#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 ) 第一的。然后我在每次外循环迭代时将计数的出现值从tempcount 转移到counter[]。 (对于所有独特的元素)

【讨论】:

  • 这里int count[n]={0};必须动态分配内存,因为n不是编译时常量
【解决方案2】:

这正是你所需要的(数组中每个数字的数量):

// 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

好吧,让我们写一些基本的代码,但首先让我们考虑一个算法(它不是最有效的,但更容易理解):

最容易理解的方法是遍历数组中的每个数字并将一些相应的计数器加一。让它成为一对,第一个元素是我们的数字,第二个是计数器:

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完全一样的解决方案(同样的想法),所以我希望它可以帮助你理解,第一个解决方案是如何工作的

【讨论】:

  • 我在 C++ 方面并不先进,我在基础方面
  • 我不懂地图
  • @ProBoy,我现在正在写一个基本的解决方案,它很快就会出现在我的答案中:)
  • 我在 C++ 方面并不先进,我是在基础方面——对于 C++ 的“基础”是什么是主观的。 map 是基本的,了解它们是什么以及如何使用它们是“基本”。如果你想与另一种语言 Python 进行比较,Python 中的“地图”几乎是在学习该语言的第一周就学会了。
  • @PaulMcKenzie,但在 python 中map 完全不同:它是一个函数,将函数应用于集合的每个元素。在 C++ 中它是一个容器!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-05-07
  • 1970-01-01
  • 2019-02-25
  • 1970-01-01
  • 2016-05-21
  • 1970-01-01
  • 2018-06-12
相关资源
最近更新 更多