#include #include #include // This is an interesting problem inspired by // Advent of Code: // // https://adventofcode.com/ // // Write a function that takes a C-style string // and a value n between 1 and 26. // // The function should find the first sequence of // n consecutive characters in which all n // characters are different. // // Return the index immediately after the last // character in this sequence. // // For example, consider // // "abcade" // // with n == 4. The first sequence of four unique // characters is // // "bcad" // // which occupies indices 1, 2, 3, and 4. // Consequently, the function should return 5. // // The string is guaranteed to contain only // lower-case letters. // // If you reach the null character '\0' without // finding such a sequence, return the index of // the null character. // // The last 26 characters of str0 are unique, so // there is always a solution for str0 when // 1 <= n <= 26. // Function declarations std::size_t find_unique( char const str[], std::size_t const n ); int main(); // Function definitions int main() { char str0[201]{ "vzpgaywplurlzyvjeykqssbgh" "qniqyhgrsqsrkrtjswxrgmtsy" "grwhprvpoivwxqgecvosbzlta" "afeehkdmosrynydlmoyxizwag" "nrmgevgaukcaclnicbaqpwmze" "oqguicocngzztgmdcmfbkgiml" "bpxyhegkdxmflrqkopjpfzcne" "izhfcdkpmgnwrqsjoatxluvyb" }; char str1[201]{ "zagheyjefwhyydepijjwyowrw" "rpfsyqlofmxaxuipodudfbmkf" "elfccznazfewpmvfyuxnattcy" "lzhdpsfxztkbwazkddjeiogqq" "ubxncpjrrnonzmlzvykkvpkun" "kngiwkkrisekwukdhqeoxeuec" "pjxowxtidbqeobitkgwpsqydq" "ueyhevqxuussfiitjlbqxmhuv" }; std::cout << find_unique( str0, 10 ) << std::endl; std::cout << find_unique( str1, 10 ) << std::endl; return 0; } std::size_t find_unique( char const str[], std::size_t const n ) { assert( (1 <= n) && (n <= 26) ); // Enter your implementation here. return 0; } // Hint: This one is a challenge, so try it on // your own first. // // Remember that if ch is of type char and ch is // a lower-case letter between 'a' and 'z', then // // ch - 'a' // // has a value between 0 and 25. // // Consequently, you can use this value as an // index into an array of size 26: // // bool found[26]{}; // char const ch{ str[k] }; // found[ch - 'a'] = true; // // For each possible starting position, you could // use such an array to remember which characters // you have already encountered. // // If you are even more clever, you might use the // value between 0 and 25 to identify one bit in // a 32-bit unsigned integer. // Here is one solution: /* std::size_t find_unique( char const str[], std::size_t const n ) { assert( (1 <= n) && (n <= 26) ); for ( std::size_t start{ 0 }; str[start] != '\0'; ++start ) { bool found[26]{}; bool unique{ true }; for ( std::size_t k{ 0 }; k < n; ++k ) { if ( str[start + k] == '\0' ) { // There are fewer than n characters // remaining, so no later starting // position can contain n characters. return start + k; } std::size_t const index{ static_cast( str[start + k] - 'a' ) }; if ( found[index] ) { unique = false; break; } found[index] = true; } if ( unique ) { return start + n; } } // This occurs only when str is empty. return 0; } */