Как определить и посчитать уникальные символы в потоке строки - PullRequest
0 голосов
/ 10 февраля 2019

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

district1 D D R R D
district2 D G R R R I
district3 I D D R D D 
district4 R R I

Как применить streamstream для идентификации, чтения, подсчета отдельных символов в строке?Я буду использовать эти значения позже в коде для вычисления некоторых соотношений.

Map<string, double> gerrymanderingRatios(string file) {
    Map<string, double> gerryMap;
    ifstream file_in(file);

    if (file_in) {
        string line, ignoreMe;
        stringstream ss;
        while (file_in >> ignoreMe, getline(file_in, line)) {
            /* ignore first token and count instances of each
            char in the line. */
        }
        file_in.close();

        /* calculate ratios for "political party" (char)
        and insert into the map. */
    }
    return gerryMap;

Результатом будет карта;ключи - это стороны (char), а значения - это отношения, т.е. {{"D", 0.4543}, {"R", 1.0323}, {"I", 0.343}}

1 Ответ

0 голосов
/ 11 февраля 2019

Я бы сделал что-то подобное, используя исключения, чтобы узнать, есть ли символ на карте или нет.Редактирование вашего кода:

#include<iostream>
#include<fstream>
#include<string>
#include<sstream>
#include<map>
#include<stdexcept>

using namespace std;

map<string, double> gerrymanderingRatios(string file) {
    map<string, int> countMap;
    map<string, double> gerryMap;
    ifstream file_in(file);

    if (file_in) {
        string line, ignoreMe, ch;
        int total = 0;
        while (file_in >> ignoreMe, getline(file_in, line)) {
            /* ignore first token and count instances of each
            char in the line. */
            stringstream ss(line);
            while(ss >> ch) {
                try {
                    countMap.at(ch)++;
                } catch(const out_of_range& oor) {
                    countMap[ch] = 1;
                }
                total++;
            }            
        }
        file_in.close();

        // print the final count for each element
        map<string, int>::iterator it;
        for (it = countMap.begin(); it != countMap.end(); it++ ) {
            cout << it->first
               << ':'
               << it->second
               << endl;
        }

        /* calculate ratios for "political party" (char)
        and insert into the map. */

        //calculate ratios
        for (it = countMap.begin(); it != countMap.end(); it++ ) {
            gerryMap[it->first] = (double)it->second / total;
        }

        //print total ratios
        cout << "ratios" << endl;
        map<string, double>::iterator dit;
        for (dit = gerryMap.begin(); dit != gerryMap.end(); dit++ ) {
          cout << dit->first 
               << ':'
               << dit->second
               << endl;
        }

    }
    return gerryMap;
}

int main() {
    map<string, double> ratiomap = gerrymanderingRatios("example.txt");

    //do whatever you need with the ratios

    return 0;
}

Соответствующая часть:

while(ss >> ch) {
    try {
        countMap.at(ch)++;
    } catch(const out_of_range& oor) {
        countMap[ch] = 1;
    }
    total++;
}

countMap.at(ch) сгенерирует исключение out_of_range, если ключ ch отсутствует на карте.Так что я могу попытаться увеличить значение, но если выдается исключение, оно добавляется вместо счетчика 1. Обратите внимание, что я ввел map<string, int> countMap, чтобы сохранить индивидуальные значения каждого ключа, используя целые числа, и использовал ваш * 1011.* в конце, когда я вычисляю отношения.

...