сравнение битов (по одной позиции за раз) - PullRequest
0 голосов
/ 06 декабря 2010

alt text

Изначально у меня есть пользовательские десятичные числа (0 - 15), и я превращу их в двоичные числа. Скажем, эти цифры записаны в текстовый файл, как показано на рисунке. Эти числа расположены по номерам 1. Тире - используется для разделения разных групп по 1.

Мне нужно прочитать этот файл и сравнить строки одной группы со всеми строками в группе ниже, т.е. группу 1 со всеми строками в группе 2 и группу 2 - группу 3.

Дело в том, что допускается только один столбец с разницей 0/1, и этот столбец заменяется буквой t. Если обнаружено более одного столбца различий, не пишите. Так, скажем, группа 2, 0001, с группой 3, 0011, отличается только второй столбец. однако 0010 и 0101 - это два столбца разницы.

Результат будет записан в другой файл .....

В данный момент, когда я читаю эти строки, я использую вектор string . Я сталкивался с битсетом. Важно то, что я должен получить доступ к символу по одному за раз, что означает, что я разбил вектор string на вектор char . Но кажется, что может быть более простой способ сделать это.

Я даже думал о хеш-таблице - связанный список. Имея группу 1, назначенную на H [0]. Каждое сравнение выполняется как H [current-group] с H [current_group + 1]. Но за пределами первого сравнения (сравнение 1 и 0) сравнение за пределами этого не будет работать при таком хеш-связанном способе. Поэтому я отказался от этого.

#include <iostream>
#include <fstream>
#include <vector>
#include <string>
#include <algorithm>
#include <iterator>
using namespace std;

int main() {
  ifstream inFile("a.txt");
  vector<string> svec;
  copy(istream_iterator<string>(inFile), istream_iterator<string>(), back_inserter(svec));
  copy(svec.begin(), svec.end(), ostream_iterator<string>(cout,"\n"));
  for(int i = 0; i < svec.size(); i++)
  {
    cout << svec[i] << " ";
  }
  inFile.close();

  return 0;
}

Это пример кода записи его в файл .... но, как я уже сказал, в моем случае все дело в векторе кажется непрактичным ....

Любая помощь приветствуется. спасибо

Ответы [ 4 ]

1 голос
/ 07 декабря 2010

Я не понимаю ваш фрагмент кода - похоже, все, что он делает - читает во входном файле вектор строк, который затем будет содержать каждое слово, разделенное пробелами, в отдельной строке, а затем записывать его обратно 2 разными способами (один раз со словами, разделенными \n, один раз с ними, разделенными пробелами).

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

Я думаю, что структура строки файла важна - верно? В этом случае вам лучше использовать функцию global getline() в заголовке <string> , которая считывает всю строку (а не слово, разделенное пробелами) в строку. (По общему признанию, эта функция довольно хорошо скрыта!) Кроме того, вам на самом деле не нужно читать все строки в векторе, а затем обрабатывать их - это более эффективно и на самом деле проще распределять их до чисел или наборов битов по ходу :

vector<unsigned> last, curr;    // An unsigned can comfortably hold 0-15
ifstream inf("a.txt");

while (true) {
    string line;
    getline(inf, line);    // This is the group header: ignore it
    while (getline(inf, line)) {
        if (line == "-") {
            break;
        }

        // This line contains a binary string: turn it into a number
        // We ignore all characters that are not binary digits
        unsigned val = 0;
        for (int i = 0; i < line.size(); ++i) {
            if (line[i] == '0' || line[i] == '1') {
                val = (val << 1) + line[i] - '0';
            }
        }

        curr.push_back(val);
    }

    // Either we reached EOF, or we saw a "-".  Either way, compare
    // the last 2 groups.
    compare_them_somehow(curr, last);   // Not doing everything for you ;)
    last = curr;   // Using swap() would be more efficient, but who cares
    curr.clear();
    if (inf) {
        break;   // Either the disk exploded, or we reached EOF, so we're done.
    }
}
0 голосов
/ 06 декабря 2010

в vb.net

'group_0 with group_1
            If (group_0_count > 0 AndAlso group_1_count > 0) Then
                Dim result = ""
                Dim index As Integer = 0
            Dim g As Integer = 0
            Dim h As Integer = 0
            Dim i As Integer = 0

            For g = 0 To group_0_count - 1
                For h = 0 To group_1_count - 1
                    result = ""
                    index = 0
                    For i = 0 To 3
                        If group_1_0.Items(g).ToString.Chars(i) <> group_1_1.Items(h).ToString.Chars(i) Then
                            result &= "-"
                            index = index + 1
                        Else
                            result &= group_1_0.Items(g).ToString.Chars(i)
                        End If
                    Next
                Next
            Next
        End If
0 голосов
/ 06 декабря 2010

Считайте это как целое число, тогда все, что вам нужно, это сравнение с битовыми сдвигами и битовыми масками.

0 голосов
/ 06 декабря 2010

Возможно, я неправильно понял вашу цель, но строки поддаются сравнению для сравнения элементов массива:

string first = "001111";
string next = "110111";
int sizeFromTesting = 5;
int columnsOfDifference = 0;

for ( int UU = sizeFromTesting; UU >=0; UU-- )
{
    if ( first[ UU ] != next[ UU ] )
        columnsOfDifference++;
}
cout << columnsOfDifference;
cin.ignore( 99, '\n' );
return 0;

Замена файловых потоков и связанной защиты там, где это необходимо.

Не применимо, но для буквального побитового сравнения переменных, причем обе используют маску для каждой цифры (000010 для второй цифры) Если или = 0, они совпадают: оба равны 0. Если они или = 1 и & = 1, эта цифра равна 1 для обоих. В противном случае они отличаются. Повторите эти действия для всех битов и всех чисел в группе.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...