переход через несколько циклов без указания c порядка (C ++) - PullRequest
1 голос
/ 10 февраля 2020

Я пытаюсь запустить код, который сравнивает две строки и подсчитывает, сколько последовательных букв во второй строке доступно в первой строке.

Редактировать: пример того, как должна работать функция:

longest_letter_run ("this_is_some_text", "ais_") Должен возвращать 7, потому что самая длинная буква «is_is_s» a не учитывается, поскольку в первой строке текста нет «a».

Моя проблема в том, что после запуска и подтверждения того, что следующая строка кода верна, (1)

if (word[i] == match[j]){

Я хочу вернуться к следующей итерации в (2)

for (int i=0; i < word.size(); i++){

и продолжайте до тех пор, пока условие в (1) снова не станет ложным, затем я выйду из всех циклов после этого.

Но я не уверен, как это сделать. В некоторых сообщениях предлагалось использовать флаг или использовать goto, но я не думаю, что это работает в этом случае.

Вот то, что я пока имею, который учитывает только появление букв в обеих строках (не считается последовательных букв еще)

#include <iostream>
#include <string>
using std::cin;
using std::cout;
using std::endl;
using std::string;




int longest_letter_run(string word, string match){
    int iter = 0;
    for (int i=0; i < word.size(); i++){
        for (int j=0; j <match.size(); j++){
            if (word[i] == match[j]){
                if (true){
                    ++iter;
                }

            }

        }

    }

}

Ответы [ 4 ]

1 голос
/ 10 февраля 2020
template<typename T, typename F>
size_t length_longest_sequence_maching(T&& c, F&& f) {
    size_t result = 0;
    szie_t currentLen = 0;
    for(const auto& x : c) {
       if (f(x)) { 
          result = std::max(result, ++currentLen);
       } else {
          currentLen = 0;
       }
    }
}

size_t length_longest_char_sequence(const std::string& s, const std::string& charSet)
{
    return length_longest_sequence_maching(s, 
        [](auto ch) { return std::string::npos != charSet.find(ch); });
}
1 голос
/ 10 февраля 2020

как насчет использования break? Это сломало бы только внутреннюю l oop:

for (int i=0; i < word.size(); i++)
{
    for (int j=0; j < match.size(); j++)
    {
        if (word[i] == match[j])
        {
            ++iter;
            break;
        }
    }
}
1 голос
/ 10 февраля 2020

Вместо использования сложного потока l oop я предлагаю использовать функцию:

bool inner_loop(string word,string match) { 
     for (int j=0; j <match.size(); j++){
        if (word[i] == match[j]) return true;
     }
     return false;
}


int longest_letter_run(string word, string match){
    int iter = 0;
    for (int i=0; i < word.size(); i++){
        if (inner_loop(word,match)) ++iter;
    }
    return iter;     
}
1 голос
/ 10 февраля 2020

Во-первых, примечание. if (true) бессмысленно и может быть удалено.

Чтобы ответить на ваш вопрос, если я вас правильно понимаю, вы можете использовать управляющую переменную. (как уже говорили другие, вы можете просто использовать break вместо контроля) Например:

for (int i=0; i < word.size(); i++){
    bool matched = false;
    for (int j=0; j < match.size() && !matched; j++){
        if (word[i] == match[j]){
            matched = true;
            ++iter;
        }
    }
}

Я думаю, что это больше соответствует тому, что вы хотите:

#include <iostream>
#include <algorithm>


int longest_letter_run( const std::string &word, const std::string &match ) {
    int max = 0;
    for ( int i = 0; i < word.size(); i++ ) {
        int count = 0;
        int word_idx = i;
        for ( int j = 0; j < match.size() && word_idx < word.size(); ++j, ++word_idx, ++count ) {
            if ( word[word_idx] != match[j] ) {
                break;
            }
        }
        max = std::max( max, count );
    }
    return max;
}

int main() {
    std::cout << longest_letter_run( "apples", "pp" ) << '\n';
    std::cout << longest_letter_run( "appples", "p" ) << '\n';
    std::cout << longest_letter_run( "weird", "weirdness" ) << '\n';
    std::cout << longest_letter_run( "weirdweirdne", "weirdness" ) << '\n';
    std::cout << longest_letter_run( "weirdweirdweirdnessweirdne", "weirdness" ) << '\n';

    getchar();
}

С выводом

2
1
5
7
9

РЕДАКТИРОВАТЬ:

Хорошо, согласно вашему комментарию:

Единственное условие, что они должны быть последовательными буквами в «слово», чьи буквы также находятся в «совпадении». упорядочение букв в «совпадении» не требуется.

int longest_letter_run( const std::string &word, const std::string &match ) {
    int max = 0;
    int count = 0;
    for ( int i = 0; i < word.size(); i++ ) {
        if ( match.find( word[i] ) != std::string::npos )
            ++count;
        else {
            max = std::max( max, count );
            count = 0;
        }
    }
    max = std::max( max, count );
    return max;
}

Вывод (с тем же основным, что и раньше):

2
3
5
12
26
...