Как мне упорядочить символы в выводе массива в этом вложенном цикле for?
Мой код подсчитывает, сколько вхождений символа появляется в строке, он работает, но не отображает его так, как я хочу, вероятно, из-за упорядочения таблицы ASCII.
Мой желаемый результат:
enter string value: Prog
P - 1
r - 1
o - 1
g - 1
Но вместо этого я получил его по алфавиту:
enter string value: Prog
g - 1
o - 1
P - 1
r - 1
Вот мой код:
char str[100] = "";
int sum = 0;
cout<<"Enter String Value: ";
gets(str);
//char counter uppercase
for (int i = 65; i<=90; i++)
{
sum = 0;
for (int j=0; j<sizeof(str); j++)
{
if((int)str[j] == i)
{
sum = sum + 1;
}
}
if (sum > 0)
{
cout<<(char)i<<" - "<<sum<<endl;;
}
}
//char counter lowercase
for (int i = 97; i<=122; i++)
{
sum = 0;
for (int j=0; j<sizeof(str); j++)
{
if((int)str[j] == i)
{
sum = sum + 1;
}
}
if (sum > 0)
{
cout<<(char)i<<" - "<<sum<<endl;;
}
}
PS: Мне это нужно, чтобы отдельно подсчитывать строчные и прописные буквы.
3 ответа
Сначала вы можете сделать свою программу намного меньше (по размеру) и лучше (в целом), используя
std::map
Версия 1 : вывод не отображается в порядке вставки
#include <iostream>
#include <map>
int main() {
std::string inputString;
std::cout<<"Enter a string: ";
std::getline(std::cin,inputString);
//this map maps the char to their respective count
std::map<char, int> charCount;
for(char &c: inputString)
{
charCount[c]++;
}
for(std::pair<char, int> pairElement: charCount)
{
std::cout << pairElement.first <<"-" << pairElement.second<<std::endl;
}
return 0;
}
Результат вышеупомянутой версии 1 выглядит следующим образом:
Enter a string: Prog
P-1
g-1
o-1
r-1
Обратите внимание, что в указанном выше порядке символы расположены в алфавитном порядке. Если вы хотите, чтобы вывод был в порядке, сделайте следующее:
Версия 2 : отображает вывод в нужном вам порядке вставки.
#include <iostream>
#include <map>
int main() {
std::string inputString;
std::cout<<"Enter a string: ";
std::getline(std::cin,inputString);
//this map maps the char to their respective count
std::map<char, int> charCount;
for(char &c: inputString)
{
charCount[c]++;
}
//just go through the inputString instead of map
for(char &c: inputString)
{
std::cout << c <<"-" << charCount.at(c)<<std::endl;
}
return 0;
}
Результат этой второй версии выглядит следующим образом:
Enter a string: Prog
P-1
r-1
o-1
g-1
Также вывод вышеупомянутой версии 2, когда на входе есть повторяющиеся символы, такие как "AnoopRana", будет повторяться, как показано ниже:
Enter a string: AnoopRana
A-1
n-2
o-2
o-2
p-1
R-1
a-2
n-2
a-2
Чтобы отобразить каждый символ только один раз, вы можете увидеть эту программу, которая выглядит следующим образом:
Версия 3: для отображения каждого символа ровно один раз и в порядке вставки
#include <iostream>
#include <map>
int main() {
std::string inputString;
std::cout<<"Enter a string: ";
std::getline(std::cin,inputString);
//this map maps the char to their respective count
std::map<char, int> charCount;
for(char &c: inputString)
{
charCount[c]++;
}
std::size_t i = 0;
//just go through the inputString instead of map
for(char &c: inputString)
{
std::size_t index = inputString.find(c);
if(index != inputString.npos && (index == i)){
std::cout << c <<"-" << charCount.at(c)<<std::endl;
}
++i;
}
return 0;
}
Примечание
Обе версии считают строчные и заглавные буквы отдельно, что вам и нужно. #include <filesystem>
#include <iostream>
#include <fstream>
#include <map>
#include <cmath>
#include <chrono>
#include <algorithm>
#include <vector>
#include <execution>
#include <thread>
#include <condition_variable>
#include <mutex>
#include <string>
#include <atomic>
std::vector<std::pair<char,int>> tfinal;
int main(int argc, char *argv[])
{
std::string c = "rgjukuilo";
std::for_each(std::execution::par, c.begin(), c.end(), [&](auto a){ int wr = std::count(c.begin(), c.end(), a);
tfinal.insert(tfinal.end(), { a , wr } ); });
for (auto c : tfinal)
std::cout << c.first << " " << c.second << std::endl;
}
Мне нравится этот подход, но если цель состоит в том, чтобы сохранить порядок ввода при указании количества символов, у вас должен быть какой-то способ проверить символы, которые уже были замечены. делает это за вас, но не сохраняет порядок ввода. Если вы перебираете исходную строку, чтобы обеспечить вывод по порядку, вам все равно нужен способ избежать вывода нескольких счетчиков для одного и того же символа, если он встречается более одного раза во входной строке.
В случае, когда вы перебираете входную строку, вы можете отслеживать позицию и использовать std::basic_string::find для проверки оставшейся части строки перед выводом следующего символа.
Другой способ - использовать
Например, вы могли бы сделать:
#include <iostream>
#include <string>
#include <vector>
/* returns index if c is contained in vector, vector.size() if not */
size_t vpairContains (const std::vector<std::pair<char,int>>& vp, char c)
{
size_t ndx = 0; /* zero index */
for (const auto& p : vp) { /* loop over pairs */
if (p.first == c) { /* compare char */
break;
}
ndx++; /* increment index */
}
return ndx;
}
int main (void) {
std::string input {};
std::vector<std::pair<char,int>> vp {}; /* vector pairs */
std::cout << "enter letters: "; /* get/validate string */
if (!getline (std::cin, input)) {
return 1;
}
for (const auto& c : input) { /* loop over chars */
size_t ndx = vpairContains (vp, c); /* get index in vector */
if (ndx < vp.size()) { /* check if found */
vp[ndx].second++; /* increment count */
}
else {
vp.push_back({c, 1}); /* add new element */
}
}
for (const auto& p : vp) { /* output results */
std::cout << p.first << " - " << p.second << '\n';
}
}
Пример использования / вывода
Предоставляя входную строку с несколькими вхождениями одного и того же символа, вы можете:
$ ./bin/vector_pair_char-int
enter letters: abcd-dbbccc-*-
a - 1
b - 3
c - 4
d - 2
- - 3
* - 1
Посмотрите на вещи и дайте мне знать, если это то, чего вы пытались достичь. Есть несколько способов сделать это. В