Made my IsIsogram function using an array containing a number for each letter in the alphabet that I use to track the sum of each letter in a word, then just check if the max element of the array is > 1.
Meaning I only need to loop through the word once.
bool UBullCowCartridge::IsIsogram(const FString Word)
{
// Initialise alphabet array
// a b c d e f g h i j k l m n o p q r s t u v w x y z
int32 LetterCounts[26] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
// Loop through word adding occurences of letter to alphabet array
for (int32 i = 0; i < Word.Len(); i++)
{
char Letter = Word.ToLower()[i];
++LetterCounts[Letter - 'a'];
}
// Check if maximum value in alphabet array if greater than 1
if (*std::max_element(LetterCounts, LetterCounts + 26) > 1)
{
return false;
}
return true;
}
Edit:
Iām aware this will fail if something other than a plain letter is passed to the function so Iām adding further input validation elsewhere in the program
This is looping the array when it could have just checked when the increment happened and returned without needing to go through the whole word first and then looped again.
NestedLoop is what is done in the course does
AdjacentFind sorts and then finds if any adjacent pairs are the same letter
Array1 is your implementation
Array2 is with my fixes
(the alphabet test is for the actual alphabet not the word āalphabetā)
bool UBullCowCartridge::IsIsogram(FString Word)
{
// Initialise alphabet array
// a b c d e f g h i j k l m n o p q r s t u v w x y z
int32 LetterCounts[26] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
Word.ToLowerInline();
// Loop through word adding occurences of letter to alphabet array
for (int32 i = 0; i < Word.Len(); i++)
{
char Letter = Word[i];
if (++LetterCounts[Letter - 'a'] > 1)
{
return false;
}
}
return true;
}
No idea how I missed something as obvious as checking the incremented value instantly. but I wouldāve never spotted the fact that I was calling ToLower each loop, thank you!
interesting. Are you going to teach us the AdjacentFind method.? It is deadly efficient.
How do I post codes here? Like this? Do I have to create a new topic?
This is my implementation of nested loop. I looked for an FString function to check that the string contains only alphabet but cannot find, however there is one for checking numeric string.
/[code]
bool UBullCowCartridge::IsIsogram(FString Guess)
{
int i{};
int j{};
for ( i = ( Guess.Len() - 1) ; i > 0; --i)
{
//PrintLine(TEXT("i is %i ,Guess[i] is %c "), i, Guess[i]); //debug line
for (j = (i - 1) ; j >= 0; --j)
{
//PrintLine(TEXT("j is %i ,Guess[j] is %c "), j, Guess[j]); //debug line
if (Guess[i] == Guess[j])
{
return false;
}
}
}
return true;
You can create a new topic for things like this, but make sure you use the right category (this would probably be in the UE4 -> Ask category)
You format a multi-line code block with 3 grave (also called back-tick) symbols (```) on the line above the first line of code, and three more after the last line of code. You can also use HTML notation
with a <code> tag
Also if you want to check if a string contains only letters you can loop through each char and use isalpha()
Well first some disclaimers. These are tested with standard C++ and not Unreal to easily benchmark with Google Benchmark, so the numbers arenāt accurate with Unreal but should give a good indication of how it should perform as the only difference should be with the uses of ToLower.
One thing I forgot to do in the last post was to convert all the other benchmarks to use the ToLower alternative I created for the string as the rest of the tests just did tolower in the loop to not need to convert every character if itās not needed. So with Unreal you can use FChar::ToLower which is the same thing as tolower.
So here is the updated version which uses tolower in the loop. (also with an addition test for a 9 letter isogram).
Hi All,
Thought Iāll share with you my version here as I believe it is pretty efficient as well (only one loop and as soon as first duplicate is found function returns false):