Russian Qt Forum

Qt => Общие вопросы => Тема начата: Alexander от Февраль 13, 2010, 15:22



Название: Вопрос о сравнении вхождений QStringList'ов
Отправлено: Alexander от Февраль 13, 2010, 15:22
Начал изучать Qt совсем недавно и на сей момент столкнулся с достаточно простой проблекой, но... Помогите, кто сможет)

Есть переменная QStringList Token, в которой хранится список введенных пользователем слов. В другую переменную QStringList StopList, при старте программы, загружается список "стоп" слов, которые нужно удалить из списка первой переменной. Понимаю, что весь алгоритм сводится к сравнению элементов списков и при нахождении совпадений - удалению, но не получается....

Сим кодом загружается список "стоп" слов:

Код:
void Tokenizer::loadStopWord() {
    QFile stopword (qApp->applicationDirPath()+"/files/stop_word_list.txt");
    if (!stopword.open(QIODevice::ReadOnly|QIODevice::Text))
    {
        QMessageBox msgBox;
        msgBox.setText("Can't load the file Stop_word_list.txt!");
        msgBox.exec();
    }
    QTextStream stopwordStream(&stopword);
    while (!stopwordStream.atEnd())
    {
      StopList.append((stopwordStream.readLine()).toLower());
    }
}

Далее часть функции tokenization должна собственно сравнивать строки:

Код:
void Tokenizer::tokenization() {
int t=0;
while (t!=-1)
{
    for (int i=0; i<StopList.length(); i++)
    {
        if (StopList[i]==Token[t])
            Token.removeAll(Token[t]);
    }
t--;
}
ui->Token_list->addItems(Token);
}

Но в результате программа возвращает просто значение Token.


Название: Re: Вопрос о сравнении вхождений QStringList'ов
Отправлено: BRE от Февраль 13, 2010, 15:43
t = 0; после первой итерации t становится равно -1, цикла завершается...
Проверяем только первое слово из Token.



Название: Re: Вопрос о сравнении вхождений QStringList'ов
Отправлено: Alexander от Февраль 13, 2010, 16:14
Логично... =) А чему же тогда должен быть равен t?


Название: Re: Вопрос о сравнении вхождений QStringList'ов
Отправлено: BRE от Февраль 13, 2010, 16:23
Логично... =) А чему же тогда должен быть равен t?
Наверное, количеству элементов в Token:
Token.size()


Название: Re: Вопрос о сравнении вхождений QStringList'ов
Отправлено: Alexander от Февраль 13, 2010, 16:41
переписал так:

Код:
int t=Token.size();
while (t!=-1) ...

выдает Runtime Error


Название: Re: Вопрос о сравнении вхождений QStringList'ов
Отправлено: Kolobok от Февраль 13, 2010, 17:23
Код:
foreach(QString s,StopList)
  Token.removeAll(s);


Название: Re: Вопрос о сравнении вхождений QStringList'ов
Отправлено: Alexander от Февраль 14, 2010, 06:20
Спасибо! С foreach работает)

Но чтобы не оставалось так сказать пробелов в знаниях, как можно было бы переписать код,используя while?

Пробовал использовать также цикл с
Код:
for (int t=0; t<Token.length(); t++)
и вроде бы итерации шли до конца, но вот почему-то не все "стоп" слова удалялись из списка Token, а как-то выборочно. И если сами "стоп" слова запихать в Token и обработать,то возникала опять же Runtime Error. В чем может быть ошибка? Код соответственно такой же, только с for:
Код:
for (int t=0; t<Token.length(); t++)
{
    for (int i=0; i<StopList.length(); i++)
    {
        if (StopList[i]==Token[t])
            Token.removeAll(Token[t]);
    }
}


Название: Re: Вопрос о сравнении вхождений QStringList'ов
Отправлено: niXman от Февраль 14, 2010, 09:10
по взрослому, делается так:
Код
C++ (Qt)
std::list<std::string> tokens = {"1", "2", "3", "3", "6", "2", "9"};
tokens.sort(); // обязательно сортируем
std::list<std::string> stop_list = {"7", "2", "3", "5"};
stop_list.sort(); // обязательно сортируем
 
std::set_intersection(stop_list.begin(), stop_list.end(),
 tokens.begin(), tokens.end(),
 [&](auto x) { std::remove(tokens.begin(), tokens.end(), *x); } // внимание лямбда!
 );
 
но нужен компилятор gcc-4.5.0

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

кстати вместо лямбда, можно использовать функтор с перегруженным operator()


Название: Re: Вопрос о сравнении вхождений QStringList'ов
Отправлено: niXman от Февраль 14, 2010, 09:28
кстати, для того чтоб не было гемора с индексами, выходом за пределы - изобрели итераторы ;)


Название: Re: Вопрос о сравнении вхождений QStringList'ов
Отправлено: Alexander от Февраль 14, 2010, 11:06
2 niXman
Спасибо за код, попытаюсь разобраться в нем) Но пока, что лямбда, что функтор, всё звучит для меня одинаково... :(

И еще, был бы признателен за информацию о том, что такое многомерные массивы в C++ Qt, и как с ними правильно работать, как многомерный массив оформить в txt файле. =)


Название: Re: Вопрос о сравнении вхождений QStringList'ов
Отправлено: Igors от Февраль 15, 2010, 06:07
На контейнерах можно так
Код:
void RemoveStopsFromLst( QStringList & lst, const QStringList & stopLst )
{
// QSet для быстрого поиска
  QSet <QString> stop = stopLst.toSet();

// выходной лист чтобы не связываться с мутными удалениями из контейнера
  QStringList dst;

// отбираем
  for (int i = 0; i < lst.size(); ++i)
   if (!stop.contains(lst[ i ])
    dst.push_back(lst[ i ]);

// переписываем
  lst = dst;
}


Название: Re: Вопрос о сравнении вхождений QStringList'ов
Отправлено: Alexander от Февраль 15, 2010, 13:03
А есть ли какие-то отличия в работе этих трех вариантов кода? Если да, то какие и где?)

Код:
foreach(QString s,StopList)
  Token.removeAll(s);

Код:
std::list<std::string> tokens = {"1", "2", "3", "3", "6", "2", "9"};
tokens.sort(); // обязательно сортируем
std::list<std::string> stop_list = {"7", "2", "3", "5"};
stop_list.sort(); // обязательно сортируем
 
std::set_intersection(stop_list.begin(), stop_list.end(),
  tokens.begin(), tokens.end(),
  [&](auto x) { std::remove(tokens.begin(), tokens.end(), *x); } // внимание лямбда!
  );

и

Код:
void RemoveStopsFromLst( QStringList & lst, const QStringList & stopLst )
{
// QSet для быстрого поиска
  QSet <QString> stop = stopLst.toSet();

// выходной лист чтобы не связываться с мутными удалениями из контейнера
  QStringList dst;

// отбираем
  for (int i = 0; i < lst.size(); ++i)
   if (!stop.contains(lst[ i ])
    dst.push_back(lst[ i ]);

// переписываем
  lst = dst;}


Название: Re: Вопрос о сравнении вхождений QStringList'ов
Отправлено: Igors от Февраль 15, 2010, 16:51
А есть ли какие-то отличия в работе этих трех вариантов кода? Если да, то какие и где?)
Лучше спросить о достоинствах каждого варианта, тогда

1) Краткость/лаконичность

2) Демонстрация богатых возможностей библиотеки (и своей эрудиции)

3) Скорость


Название: Re: Вопрос о сравнении вхождений QStringList'ов
Отправлено: niXman от Февраль 15, 2010, 22:10
Цитировать
2) Демонстрация богатых возможностей библиотеки
естественно! как писать идеальный код на С++ не зная STL и стандарта С++.

Цитировать
и своей эрудиции
вам знакомо? -
Код
C++ (Qt)
учиться, учиться, еще раз учиться(как-то так)...
не вижу ничего плохого в этом.

Цитировать
3) Скорость
;D

вот где скорость:
Код
C++ (Qt)
std::list<std::string> tokens = {"1", "2", "3", "3", "6", "2", "9"};
tokens.sort(); // обязательно сортируем
std::list<std::string> stop_list = {"7", "2", "3", "5"};
stop_list.sort(); // обязательно сортируем
 
std::list<std::string> dst;
 
std::set_intersection(stop_list.begin(), stop_list.end(),
 tokens.begin(), tokens.end(),
                                                 std::back_inserter(dst)
                         );
 

Igors
кстати, забыли упомянуть о "независимости" от сторонних библиотек, соответствии стандарту программирования, и 100% переносимости кода.


Название: Re: Вопрос о сравнении вхождений QStringList'ов
Отправлено: Igors от Февраль 16, 2010, 10:29
Код:
tokens.sort(); // обязательно сортируем
А кто Вам разрешил менять порядок слов в списке? Извольте повоэиться с указателями, посмотрим как вырастет объемчик.

кстати, забыли упомянуть о "независимости" от сторонних библиотек, соответствии стандарту программирования, и 100% переносимости кода.
Да, об этом мне лучше промолчать, потому что каждый раз когда я перетаскиваю сделанное c Mac на Вындоуз MSVC - я с ужасом думаю какую еще подлянку мне подсунет мелкософт и сколько дней (или недель) уйдет на то чтобы весь STL работал в Debug и Release

естественно! как писать идеальный код на С++ не зная STL и стандарта С++.
Никто и не говорил что не нужно знать стандарт. Вот только мне кажется что лучше не тот программист, который больше знает, а который умеет искать и находить решения.


Название: Re: Вопрос о сравнении вхождений QStringList'ов
Отправлено: niXman от Февраль 16, 2010, 10:38
Цитировать
А кто Вам разрешил менять порядок слов в списке?
ну да, никто.

Цитировать
Да, об этом мне лучше промолчать, потому что каждый раз когда я перетаскиваю сделанное c Mac на Вындоуз MSVC - я с ужасом думаю какую еще подлянку мне подсунет мелкософт и сколько дней (или недель) уйдет на то чтобы весь STL работал в Debug и Release
не секрет что микрософтстудия и ее версия STL, слабо соответствуют стандарту.
тем не менее, мне не известны случаи НЕпереносимости или НЕсоответствия поведения программ, написанных на STL.

Цитировать
Никто и не говорил что не нужно знать стандарт. Вот только мне кажется что лучше не тот программист, который больше знает, а который умеет искать и находить решения.
незнание STL и алгоритмов, зачастую "создает" программистов-велоизобретателей. но они же находят решение, пусть через *опу, но находят ;D


Название: Re: Вопрос о сравнении вхождений QStringList'ов
Отправлено: Авварон от Февраль 16, 2010, 12:53
велосипед - это лямбды в с++


Название: Re: Вопрос о сравнении вхождений QStringList'ов
Отправлено: niXman от Февраль 16, 2010, 14:50
Цитировать
велосипед - это лямбды в с++
хм...
а пояснить?


Название: Re: Вопрос о сравнении вхождений QStringList'ов
Отправлено: Авварон от Февраль 16, 2010, 14:54
зачем они там? единственное что приходит в голову - страуструпу стало завидно что они есть в шарпе.
с++ - это ООП язык а не лисп какой-нибудь. Его надо упрощать, а не добавлять новых "мегафич".


Название: Re: Вопрос о сравнении вхождений QStringList'ов
Отправлено: break от Февраль 16, 2010, 15:27
Цитировать
Его надо упрощать, а не добавлять новых "мегафич".
А разве они не удобны при передачи параметрами во всякие алгоритмы сортировки, сравнения и т.д. Особенно если размер лямбды небольшой?


Название: Re: Вопрос о сравнении вхождений QStringList'ов
Отправлено: Авварон от Февраль 16, 2010, 15:43
в любом случае здравый смысл подсказывает не писать куски кода, юзающиеся только в 1м месте, то есть сохранить их в где-то.  Смысл тогда лямбды? Просто я как бы писал на лиспе (в тч работал с графикой) и не вижу в этом ничего хорошего.


Название: Re: Вопрос о сравнении вхождений QStringList'ов
Отправлено: niXman от Февраль 16, 2010, 15:53
Авварон, имхо, ваши суждение наивны. спасибо, поржал :D

Цитировать
в любом случае здравый смысл подсказывает не писать куски кода, юзающиеся только в 1м месте
пример:
Код
C++ (Qt)
auto func = [](auto x) { return x*x; }
auto r1 = func(2);
auto r2 = func(4);
 

Цитировать
с++ - это ООП язык а не лисп какой-нибудь
в с++, лямбда, и есть объект. анонимный, полноценный объект!

Цитировать
Просто я как бы писал на лиспе (в тч работал с графикой) и не вижу в этом ничего хорошего.
наверняка так же как и на с++ ;)

идите учитесь батенька.


Название: Re: Вопрос о сравнении вхождений QStringList'ов
Отправлено: break от Февраль 16, 2010, 18:56
оффтоп:
niXman а вам я гляжу нравится оскорблять и унижать других... Мне например кажется мысль Аварона
Цитировать
не писать куски кода, юзающиеся только в 1м месте
вполне адекватной - по крайней мере поддерживать программу написанную без чрезмернорго увлечения лямбда думаю будет проще, например ваш пример

Код
C++ (Qt)
auto func = [](auto x) { return x*x; }
auto r1 = func(2);
auto r2 = func(4);

примет более запутанный вид в реальном коде когда r1, r2, ..... r10, .....r150 будут разбросаны по коду в разных местах, разных модулях и т.п.

Я собственно не против лямбда - хотелось бы просто чтобыы ВСЕ проявляли уважение к мнениям других а не кричали "ОБОСРАТЬСЯ, ПОРЖАЛ, ГЫ ШНЯГА, ШЛЯПА, КОНЬ"

ты ж не 14-летний подросток?


Название: Re: Вопрос о сравнении вхождений QStringList'ов
Отправлено: niXman от Февраль 16, 2010, 19:34
Цитировать
niXman а вам я гляжу нравится оскорблять и унижать других...
это вы так глядите ;D

Цитировать
Я собственно не против лямбда - хотелось бы просто чтобыы ВСЕ проявляли уважение к мнениям других а не кричали "ОБОСРАТЬСЯ, ПОРЖАЛ, ГЫ ШНЯГА, ШЛЯПА, КОНЬ"
пох :)

по коду, комментировать не стану. т.к. вы в очередной раз демонстрируете свое невежество.


Название: Re: Вопрос о сравнении вхождений QStringList'ов
Отправлено: niXman от Февраль 16, 2010, 20:04
Цитировать
r1, r2, ..... r10, .....r150 будут разбросаны по коду в разных местах, разных модулях и т.п.
это результат лямбда выражения. в данном случае, это int. не вижу надобности разбрасывать по коду программы, 150 переменных.
вы ведь не разбрасываете по коду программы 150 строковых переменных. хотя... :)


Название: Re: Вопрос о сравнении вхождений QStringList'ов
Отправлено: Авварон от Февраль 16, 2010, 20:37
а по типу такого изврата можо писать в новом с++?
Код:
public class HelloWorldSwing {
    private static void createAndShowGUI() {
        BLABLABLABLABLA
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                createAndShowGUI();
            }
        });
    }
}


Название: Re: Вопрос о сравнении вхождений QStringList'ов
Отправлено: break от Февраль 16, 2010, 21:20
Цитировать
по коду, комментировать не стану. т.к. вы в очередной раз демонстрируете свое невежество.
А я никакой код и не приводил - кроме твоего! ;D

Про невежество сказки можешь рассказывать сколько влезет ты уже пытался обвинить меня в "быдлокоде", однако когда попросили подтвердить примером - это ничем не закончилось. Можешь продолжать считать себя великим умником - только не думай что так будет думать кто-то еще  ;D


Название: Re: Вопрос о сравнении вхождений QStringList'ов
Отправлено: niXman от Февраль 17, 2010, 06:33
забавный какой :)


Название: Re: Вопрос о сравнении вхождений QStringList'ов
Отправлено: Авварон от Февраль 17, 2010, 23:48
2 никсман
ты если троллишь, то тролль тоньше... я как модер насмотрелся на таких:)


Название: Re: Вопрос о сравнении вхождений QStringList'ов
Отправлено: Alexander от Февраль 19, 2010, 05:59
Не хочется прерывать ваш спор, но все же...

Случайно наткнулся на такую проблему со своими списками StopList и Token:
Скажем, в списке StopList есть слово с апострофом. Ну, например, o'clock. И пользователь грузит в список Token из тхт файла тоже слово, вот только оно вида o’clock (разное начертание апострофов). Эти два слова при сравнении проходят как разные и o’clock не удаляется... Можно как-то исправить эту проблему? Тут с кодировкой что-то сделать надо я так думаю, а что..?

И почему не стОит сортировать списки перед их сравнением? 


Название: Re: Вопрос о сравнении вхождений QStringList'ов
Отправлено: break от Февраль 19, 2010, 10:13
если это эти символы
Цитировать
`
и
Цитировать
'

то это разные апострофы в одной кодировке - просто в процессе импорта приведи опострофы к одному виду заменой (есть ф-я в QString) и потом спокойно сравнивай


Название: Re: Вопрос о сравнении вхождений QStringList'ов
Отправлено: Alexander от Февраль 19, 2010, 10:59
Мысль хорошая! Но вот апострофы не
Цитировать
`
и
Цитировать
'

а такие (в частности первый)
Цитировать
’ (1)
Цитировать
' (2)

Пробовал ставить замену при импорте, но в тексте остается всё тотже (1)... Ради интереса задал удалять символ (1), но программа его просто игнорирует, не видит.

Это проблема, т.к. если текст писать не в самом тхт, а копировать из ворда скажем, то все апострофы имеют вид (1)



Название: Re: Вопрос о сравнении вхождений QStringList'ов
Отправлено: Alexander от Февраль 20, 2010, 09:31
Может всё же проблема в кодировке?