无法正确终止 cstring
Cannot terminate cstring properly
我正在编写一个程序来查找最常输入的字符并将其输出,但如果它小于数组值,则垃圾字符会接管输出。我试过将 null 放在多个地方。放在最后,放在开头。不知为何一直给我垃圾字符╠
#include <iostream>
using namespace std;
void getMaxCharfrequ(char arr[], int size) {
arr[0] = '[=10=]';
char maxChar = ' ';
int maxfreq = 0;
for (int i = 0; i < size; i++)
{
int count = 1;
for (int j = i + 1; j < size; j++)
if (arr[i] == arr[j])
count++;
if (count > maxfreq)
maxfreq = count;
}
for (int i = 0; i < size; i++)
{
int count = 1;
for (int j = i + 1; j < size; j++)
if (arr[i] == arr[j])
count++;
if (count == maxfreq)
maxChar = arr[i];
}
cout << "The max character frequency is " << maxChar << " with frequency " << maxfreq;
}
#define size 15
void main() {
char arr[size];
arr[0] = '[=10=]';
cout << "Please enter your string: ";
cin >> arr;
getMaxCharfrequ(arr, size);
}
您的代码存在多个问题。在讨论问题之前,建议 - 阅读 C++
中的 std::string
并开始使用它而不是普通的 C
样式字符数组。我将在您的程序中使用 std::string
留给您。下面的答案指出了您现有代码中的问题。让我们一一讨论:
第一个:
在main()
函数中,你在做
arr[0] = '[=10=]';
在接受用户输入之前。它不是必需的,因为 cin
在读取 char *
.
时在末尾添加了一个空终止符
第二:
您正在这样阅读用户输入 -
cin >> arr;
当用户输入超过 15
个字符时会发生什么?
至少使用cin.get (arr, size)
。最好是使用 std::string
,而不是普通的 char
数组。
第三:
您正在将 size
传递给 getMaxCharfrequ()
函数。 size
是将扩展为值 15
的宏。在 getMaxCharfrequ()
函数中,您正在迭代循环直到 size
,因此无论输入用户给出什么,循环都会迭代 15
次,这是不正确的。这也是您面临的问题的根本原因。相反,循环应该迭代输入字符串中的字符数,例如,如果用户输入字符串 hello
,循环应该只迭代 5
个字符。您应该将输入字符串的长度而不是 size
传递给 getMaxCharfrequ()
函数,或者您也可以迭代直到字符串的 [=38=]
个字符,在这种情况下,您不需要传递字符串的长度。
第四:
在getMaxCharfrequ()
函数中,第一条语句是
arr[0] = '[=10=]';
这意味着,您正在用空终止字符覆盖用户输入的第一个字符。你不需要这样做。
第五:
您不需要再次重复字符串来识别最大频率字符。相反,您可以在计算字符串中字符的频率时执行此操作。只记录count > maxfreq
.
时的字符
第六:
main()
的return类型应该是int
。
第七:
这个
using namespace std;
是bad practice,避开它。
把这些加在一起,可以做到:
#include <iostream>
#include <cstring>
void getMaxCharfrequ(char arr[], size_t size) {
char maxChar = ' ';
int maxfreq = 0;
for (size_t i = 0; i < size; i++) {
int count = 1;
for (size_t j = i + 1; j < size; j++) {
if (arr[i] == arr[j]) {
count++;
}
}
if (count > maxfreq) {
maxfreq = count;
maxChar = arr[i];
}
}
if (arr[0] == '[=14=]') {
std::cout << "Input string is empty" << std::endl;
} else {
std::cout << "The max character frequency is " << maxChar << " with frequency " << maxfreq << std::endl;
}
}
#define size 15
int main() {
char arr[size];
std::cout << "Please enter your string: ";
std::cin.get(arr, size);
getMaxCharfrequ(arr, strlen(arr));
return 0;
}
输出:
# ./a.out
Please enter your string: helloworld
The max character frequency is l with frequency 3
# ./a.out
Please enter your string:
Input string is empty
# ./a.out
Please enter your string: aaabbbbcc
The max character frequency is b with frequency 4
# ./a.out
Please enter your string: aaabbggggg
The max character frequency is g with frequency 5
答案已给出并被接受。我想另外介绍一个更现代的 C++ 解决方案,它适用于任何可迭代容器。
请看下面的例子:
#include <iostream>
#include <utility>
#include <unordered_map>
#include <queue>
#include <vector>
#include <iterator>
#include <type_traits>
#include <string>
#include <list>
// Some Alias names for later easier reading --------------------------------------------------------------------------
template <typename Container>
using ValueType = std::ranges::range_value_t<Container>;
template <typename Container>
using Pair = std::pair<ValueType<Container>, size_t>;
template <typename Container>
using Counter = std::unordered_map<ValueType<Container>, size_t>;
template <typename Container>
using UnderlyingContainer = std::vector<Pair<Container>>;
// Predicate Functor
template <class Container> struct LessForSecondOfPair {
bool operator ()(const Pair<Container>& p1, const Pair<Container>& p2) { return p1.second < p2.second; }
};
template <typename Container>
using MaxHeap = std::priority_queue<Pair<Container>, UnderlyingContainer<Container>, LessForSecondOfPair<Container>>;
// Calculate max element ---------------------------------------------------------------------------------------------
template <class Container>
auto topFrequent(const Container& data) {
if constexpr (std::ranges::range<Container>) { // Evaluated at compile time
// Count all occurences of data
Counter<Container> counter{};
for (const auto& d : data) counter[d]++;
// Build a Max-Heap
MaxHeap<Container> maxHeap(counter.begin(), counter.end());
// Return most frequent element
return maxHeap.top().first;
}
else
return data;
}
// Test
int main() {
std::vector testVector{ 1,2,2,3,3,3,4,4,4,4,5,5,5,5,6,6,6,6,6,7 };
std::cout << "Most frequent is: " << topFrequent(testVector) << "\n";
std::list testList{ 1,2,2,3,3,3,4,4,4,4,5,5,5,5,6,6,6,6,6,7 };
std::cout << "Most frequent is: " << topFrequent(testList) << "\n";
double cStyleArray[] = { 1.1, 2.2, 2.2, 3.3, 3.3, 3.3 };
std::cout << "Most frequent is: " << topFrequent(cStyleArray) << "\n";
std::string s{ "abbcccddddeeeeeffffffggggggg" };
std::cout << "Most frequent is: " << topFrequent(s) << "\n";
double value = 12.34;
std::cout << "Most frequent is: " << topFrequent(value) << "\n";
return 0;
}
基本上无所谓,用数组还是std::string
。该算法适用于任何类型的可迭代容器。
已经给出了很好的答案,但这里有一个更简单的答案。
#include <iostream>
#include <map>
int main(void) {
std::map<char, int> map;
std::string input = "aaabbcddaaaddkladfaa";
int max_freq = 0;
char max_char;
for (auto ch : input) {
map[ch]++;
if (map[ch] > max_freq) {
max_freq = map[ch];
max_char = ch;
}
}
std::cout << "Character '" << max_char
<< "' is most frequent, which is appeared " << max_freq << " times";
return 0;
}
我正在编写一个程序来查找最常输入的字符并将其输出,但如果它小于数组值,则垃圾字符会接管输出。我试过将 null 放在多个地方。放在最后,放在开头。不知为何一直给我垃圾字符╠
#include <iostream>
using namespace std;
void getMaxCharfrequ(char arr[], int size) {
arr[0] = '[=10=]';
char maxChar = ' ';
int maxfreq = 0;
for (int i = 0; i < size; i++)
{
int count = 1;
for (int j = i + 1; j < size; j++)
if (arr[i] == arr[j])
count++;
if (count > maxfreq)
maxfreq = count;
}
for (int i = 0; i < size; i++)
{
int count = 1;
for (int j = i + 1; j < size; j++)
if (arr[i] == arr[j])
count++;
if (count == maxfreq)
maxChar = arr[i];
}
cout << "The max character frequency is " << maxChar << " with frequency " << maxfreq;
}
#define size 15
void main() {
char arr[size];
arr[0] = '[=10=]';
cout << "Please enter your string: ";
cin >> arr;
getMaxCharfrequ(arr, size);
}
您的代码存在多个问题。在讨论问题之前,建议 - 阅读 C++
中的 std::string
并开始使用它而不是普通的 C
样式字符数组。我将在您的程序中使用 std::string
留给您。下面的答案指出了您现有代码中的问题。让我们一一讨论:
第一个:
在main()
函数中,你在做
arr[0] = '[=10=]';
在接受用户输入之前。它不是必需的,因为 cin
在读取 char *
.
第二:
您正在这样阅读用户输入 -
cin >> arr;
当用户输入超过 15
个字符时会发生什么?
至少使用cin.get (arr, size)
。最好是使用 std::string
,而不是普通的 char
数组。
第三:
您正在将 size
传递给 getMaxCharfrequ()
函数。 size
是将扩展为值 15
的宏。在 getMaxCharfrequ()
函数中,您正在迭代循环直到 size
,因此无论输入用户给出什么,循环都会迭代 15
次,这是不正确的。这也是您面临的问题的根本原因。相反,循环应该迭代输入字符串中的字符数,例如,如果用户输入字符串 hello
,循环应该只迭代 5
个字符。您应该将输入字符串的长度而不是 size
传递给 getMaxCharfrequ()
函数,或者您也可以迭代直到字符串的 [=38=]
个字符,在这种情况下,您不需要传递字符串的长度。
第四:
在getMaxCharfrequ()
函数中,第一条语句是
arr[0] = '[=10=]';
这意味着,您正在用空终止字符覆盖用户输入的第一个字符。你不需要这样做。
第五:
您不需要再次重复字符串来识别最大频率字符。相反,您可以在计算字符串中字符的频率时执行此操作。只记录count > maxfreq
.
第六:
main()
的return类型应该是int
。
第七:
这个
using namespace std;
是bad practice,避开它。
把这些加在一起,可以做到:
#include <iostream>
#include <cstring>
void getMaxCharfrequ(char arr[], size_t size) {
char maxChar = ' ';
int maxfreq = 0;
for (size_t i = 0; i < size; i++) {
int count = 1;
for (size_t j = i + 1; j < size; j++) {
if (arr[i] == arr[j]) {
count++;
}
}
if (count > maxfreq) {
maxfreq = count;
maxChar = arr[i];
}
}
if (arr[0] == '[=14=]') {
std::cout << "Input string is empty" << std::endl;
} else {
std::cout << "The max character frequency is " << maxChar << " with frequency " << maxfreq << std::endl;
}
}
#define size 15
int main() {
char arr[size];
std::cout << "Please enter your string: ";
std::cin.get(arr, size);
getMaxCharfrequ(arr, strlen(arr));
return 0;
}
输出:
# ./a.out
Please enter your string: helloworld
The max character frequency is l with frequency 3
# ./a.out
Please enter your string:
Input string is empty
# ./a.out
Please enter your string: aaabbbbcc
The max character frequency is b with frequency 4
# ./a.out
Please enter your string: aaabbggggg
The max character frequency is g with frequency 5
答案已给出并被接受。我想另外介绍一个更现代的 C++ 解决方案,它适用于任何可迭代容器。
请看下面的例子:
#include <iostream>
#include <utility>
#include <unordered_map>
#include <queue>
#include <vector>
#include <iterator>
#include <type_traits>
#include <string>
#include <list>
// Some Alias names for later easier reading --------------------------------------------------------------------------
template <typename Container>
using ValueType = std::ranges::range_value_t<Container>;
template <typename Container>
using Pair = std::pair<ValueType<Container>, size_t>;
template <typename Container>
using Counter = std::unordered_map<ValueType<Container>, size_t>;
template <typename Container>
using UnderlyingContainer = std::vector<Pair<Container>>;
// Predicate Functor
template <class Container> struct LessForSecondOfPair {
bool operator ()(const Pair<Container>& p1, const Pair<Container>& p2) { return p1.second < p2.second; }
};
template <typename Container>
using MaxHeap = std::priority_queue<Pair<Container>, UnderlyingContainer<Container>, LessForSecondOfPair<Container>>;
// Calculate max element ---------------------------------------------------------------------------------------------
template <class Container>
auto topFrequent(const Container& data) {
if constexpr (std::ranges::range<Container>) { // Evaluated at compile time
// Count all occurences of data
Counter<Container> counter{};
for (const auto& d : data) counter[d]++;
// Build a Max-Heap
MaxHeap<Container> maxHeap(counter.begin(), counter.end());
// Return most frequent element
return maxHeap.top().first;
}
else
return data;
}
// Test
int main() {
std::vector testVector{ 1,2,2,3,3,3,4,4,4,4,5,5,5,5,6,6,6,6,6,7 };
std::cout << "Most frequent is: " << topFrequent(testVector) << "\n";
std::list testList{ 1,2,2,3,3,3,4,4,4,4,5,5,5,5,6,6,6,6,6,7 };
std::cout << "Most frequent is: " << topFrequent(testList) << "\n";
double cStyleArray[] = { 1.1, 2.2, 2.2, 3.3, 3.3, 3.3 };
std::cout << "Most frequent is: " << topFrequent(cStyleArray) << "\n";
std::string s{ "abbcccddddeeeeeffffffggggggg" };
std::cout << "Most frequent is: " << topFrequent(s) << "\n";
double value = 12.34;
std::cout << "Most frequent is: " << topFrequent(value) << "\n";
return 0;
}
基本上无所谓,用数组还是std::string
。该算法适用于任何类型的可迭代容器。
已经给出了很好的答案,但这里有一个更简单的答案。
#include <iostream>
#include <map>
int main(void) {
std::map<char, int> map;
std::string input = "aaabbcddaaaddkladfaa";
int max_freq = 0;
char max_char;
for (auto ch : input) {
map[ch]++;
if (map[ch] > max_freq) {
max_freq = map[ch];
max_char = ch;
}
}
std::cout << "Character '" << max_char
<< "' is most frequent, which is appeared " << max_freq << " times";
return 0;
}