2010-10-11 54 views
2

我一直在关注这个论坛一段时间,但现在正式注册了。 我是一个现在学习C++的Java人。帮我把这个Java函数转换成C++

作为练习,我开始用C++重写一些我编写的Java代码(当我正在学习它时)。

有几个问题在这里帮了我很多。但我现在卡住了,需要一些帮助。

我试图解决的问题是计算数组中的最大重复字符数。这个想法是保留一个大小为26的数组作为频率数组,arr [0]是'a',arr [1]是'b'等等。为输入数组中的每个字符增加合适的位置,并最终找到最大数量的索引。

这是我的Java功能:

static char findMax(String str) { 
    int arr[] = new int[26]; 
    int i; 

    for(i=0;i<str.length();i++) 
     arr[str.charAt(i) - 'a']++; 

    int maxFreq = arr[0]; 
    int maxEleIndex = 0; 
    for(i=1;i<26;i++) 
     if(arr[i] > maxFreq) { 
      maxFreq = arr[i]; 
      maxEleIndex = i; 
     } 

    return (char)(maxEleIndex + 'a'); 
} 

这是我的C++函数:

char findMax(string str) { 
int *arr = new int[26]; 
int i; 
for(i=0;i<str.length();i++) 
    arr[str.at(i) - 'a']++; 

int maxFreq = arr[0]; 
int maxEleIndex = 0; 
for(i=1;i<26;i++) 
    if(arr[i] > maxFreq) { 
     maxFreq = arr[i]; 
     maxEleIndex = i; 
    } 

return (char)(maxEleIndex + 'a'); 

}

代码编译罚款,但没有给出正确的输出,它会报告不正确的字符为最大重复。我用指针代替引用,在函数中代替charAt。我究竟做错了什么?

回答

7

您并未将频率数组arr初始化为C++代码中的所有零。
您可以在任一两种方法解决这个问题:

修复1:

在Java数组元素得到初始化为默认值根据其类型的值。对于int,默认值为0。在您的C++版本中,动态分配的数组元素将具有垃圾的值。因为你希望他们被初始化为0你应该做的:

int *arr = new int[26](); 
         ^^ 

还要注意的是,在C++不像Java的需要解除分配您分配的任何动态分配的内存。

delete [] arr; 

在你的函数findMax结束:您可以通过使用delete操作者做到这一点。

修复2:

既然你知道你要在编译时分配(26)数组的大小,也没有必要去为动态分配。你可以这样做:

int arr[26] = {}; 

此声明的int阵列arr26元素全部初始化为0

+1

或者,由于'arr'具有固定的大小,使用'INT ARR [26] = {0};' – 2010-10-11 06:21:32

+0

@larsmans:正要添加:) – codaddict 2010-10-11 06:22:28

+1

1对未指出到删除分配的数组。当我从C++转移到Java时,GC是一种解脱。我想到有人试图走向另一个方向...... – 2010-10-11 06:31:21

2

codaddict是正确的,你应该初始化arr为全零,然后你的代码将工作。反正这里是一个重写,使其看起来更有点C++的方式

#include <algorithm> 
char findMax(const string &str) { // not necessary to copy the string arg 
int arr[26] = { 0 }; // arrays with size known at compile time 
         // can be allocated on stack 
for(string::size_type i=0;i<str.length();i++) 
    arr[str.at(i) - 'a']++; 
return static_cast<char>(std::max_element(arr, arr + 26) - arr + 'a'); 
} 
1

如果你想与C比较:

#include <stdio.h> 

char findMax (char *str){ 
    int max, i, maxIndex; 

    int arr[26] = {}; 

    for (i=0; str[i]; i++) arr[str[i] - 'a']++; 

    max = arr[0]; 
    maxIndex = 0; 
    for (i=1; i<26; i++){ 
     if (arr[i]>max){ 
      max = arr[i]; 
      maxIndex = i; 
     } 
    } 

    return (char)('a' + maxIndex); 
} 

int main(){ 
    char str[51] = "ajsheuaptoemandjeitmaneitmaneowpqlakemtnatengjfnau"; 

    printf ("char: %c\n", findMax (str)); 

    return 0; 
} 
1

尤金

你可以把下面的一行代码中的分配值为零。 或较好地避免使用动态分配,因为它不要求你和释放需要手工完成的(它不是像Java)

填充内存块:

memset的(ARR,0.26 *的sizeof(INT));分配内存后//在findMax给Arr

取消分配:

删除[] ARR; //在findMax函数返回前

1
#include <algorithm> 
#include <iostream> 
#include <climits> 
#include <string> 

using std::string; 

char findMax(const string &str) { 
    string::size_type freq[UCHAR_MAX + 1] = { 0 }; 

    for (string::const_iterator it = str.begin(); it != str.end(); ++it) 
    freq[(unsigned char) *it]++; 
    return static_cast<char>(std::max_element(freq, freq + UCHAR_MAX + 1) - freq); 
} 

int main() { 
    char letter = findMax("Hello, world. How are you?"); 
    std::cout << letter << "\n"; 
    return 0; 
} 

一些言论:

  • 在C++中,存在使用迭代器,而不是明确的数组索引的趋势。
  • 无论哪个 个字符 字节出现在字符串中,此代码都可以工作。所以要小心Unicode字符。
  • 由于char可能是有符号或无符号的,我必须将数组索引转换为保证非负的数组索引。
1
char findMax(const string& str) 
{ 
    const int alphabet_size = 26; 

    int arr[alphabet_size] = {}; 

    for_each(str.begin(), str.end(), [&](char c) { ++arr[c - 'a']; }); 

    return max = max_element(arr, arr+alphabet_size) - arr + 'a'; 
}