Jump to content
  • Advertisement
Sign in to follow this  
DarkSlayer

Permutations

This topic is 5194 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Doing some HW on permutations, and some of it is puzzeling me. SO STL IS NO NO... I understand what in "theory" is happening. I have implemented a recursive system that is ending up rotating numbers around, I think that is quite standard. but: One of the sub-tasks is to NOT display duplicate words, or permutations. So the word ASHES is only displayed once. Normally that word would come out twice (where the S and S is switching place). My first idea is to store away the permutations made ... but that is a quite bad idea. The program has to do permutations on a 15letter string ... and 15! is a freakin high number ... any ideas on how to avoid generate duplicates, when there is 2 or more equal letters? Can't find anything about it here or google ...

Share this post


Link to post
Share on other sites
Advertisement
for loop? don't see how that should work...

in a normal permutations you have these ... outputs

123 ___ sis
132 ___ ssi
213 ___ iss
231 ___ iss
312 ___ sis
321 ___ ssi

the first have 6 different outputs, the other have 3 different, 3 of them are duplicates.

My permutation should only print sis, ssi, iss.

I have the function that output the first thing, but I have really no qlues on how to remove duplicates.

Share this post


Link to post
Share on other sites
If I understand you correctly, you are getting a random string and have to generate all permutations of it with no repetitions. If that is the case, here's the solution in Python code:


word = 'ASHES'

arr = [x for x in word] # make an array out of the string
arr.sort()
print arr


def recursive(arr, curWord):
i = 0
while i < len(arr):
l = arr # take a letter
arrcpy = arr[:] # make a copy
del arrcpy
if arrcpy: # if the array is not empty
recursive(arrcpy, curWord+l)
else:
curWord += l

print curWord

while l in arr[i:]: # the point
i += 1

recursive(arr, '')




and the general idea is to first sort your string using whatever you like that the letters are in groups, like 'ashes' -> 'aehss'
Then in your recursive word-building function after using up a single letter (for recursion), you don't simply iterate to the next index of the letter. Instead, you iterate to the next LETTER, i.e. the index where you get another letter, so in case of 'aadnz' being at index 0, you would goto index 2, to letter 'd' because it is next.
Just invented that in a moment. Not guaranteed to work, though tested and giving satisfactory results :]

edit: the forum formatting treats it badly. that function invocation recursive(...) really has two ' characters

Share this post


Link to post
Share on other sites
If I understand you correctly, I have an array which is going to represent A to Z (26 letters), and then add 1 to each position for each letter?

so I have SIS ... then I add 1 in array[8] (for i), and 2 in array[18] (for s) ??

[Brainstorming]
what if I treat unike letters (SI) as an group, then have S, and rotate them around ... like (SI)S and then S(SI) ... then I rotate (SI) ..to (IS) ... then rotate it around S ... like S(IS) and then rotate to (IS)S ...

...no ... d*#%&¤%&¤%& I had it ...

mmm

[/Brainstorming] ... temporarily off ...

EDIT: didn't see your post h3r3tic, reading it now ...

Share this post


Link to post
Share on other sites
sorry, I don't have a functioning C++ compiler, just discovered my dev-cpp is dead. However I've made a D version that may be easier to read than Python anyway. So, here it comes:


import std.stdio;

void recursive(char[] arr, char[] curWord)
{
int i = 0;
while (i < arr.length)
{
char l = arr; // take a letter
char[] arrcpy = arr[0 .. i] ~ arr[i+1 .. length]; // make a copy without the single letter

if (arrcpy.length) // if the array is not empty
{
char[] newWord = curWord.dup; // copy the current word
newWord ~= l; // and add the letter to it
recursive(arrcpy, newWord); // w00t
}
else
{
curWord ~= l; // add the letter to the word
writefln(curWord); // and output it
}

// skip to the next letter
while (i < arr.length && l == arr) // the point
{
i += 1;
}
}
}

void main()
{
char[] word = "ashes";
word.sort; // sort letters in the word

writefln( word ); // output the sorted word (debug info only)
recursive(word, ""); // do the job

getchar(); // wait for a key and
} // exit ;)





edit: damn tabs vs spaces
edit: added some more comments

Share this post


Link to post
Share on other sites
Quote:
Original post by DarkSlayer
If I understand you correctly, I have an array which is going to represent A to Z (26 letters), and then add 1 to each position for each letter?

so I have SIS ... then I add 1 in array[8] (for i), and 2 in array[18] (for s) ??


That's exactly what I'm saying. Then you choose from all of the elements that have at least one element and come up with all of the possibilities that way.


#include <stdio.h>

#define MAX_LENGTH 256

void StrToUpper(char String[], const unsigned StrLen)
{
for(unsigned K=0; K<StrLen; K++)
if(String[K]>='a' && String[K]<='z')
String[K]-='a'-'A';
}

unsigned FindPermutations(char String[], const unsigned StrLen)
{
StrToUpper(String, StrLen);

unsigned Letters[26];
{
for(unsigned J=0; J<26; J++)
Letters[J]=0;
for(unsigned K=0; K<StrLen; K++)
Letters[String[K]-'A']++;
}

unsigned * CorrespondingNum;
unsigned NumDifferentLetters=0;
{
for(unsigned J=0; J<26; J++)
if(Letters[J])
NumDifferentLetters++;
CorrespondingNum=new unsigned[NumDifferentLetters];
unsigned L=0;
for(unsigned K=0; K<26; K++)
if(Letters[K])
{
CorrespondingNum[L]=K;
L++;
}
}

unsigned * NumberString=new unsigned[StrLen];
{
unsigned LettersCopy[26];
for(unsigned CopyCounter=0; CopyCounter<26; CopyCounter++)
LettersCopy[CopyCounter]=Letters[CopyCounter];

for(unsigned K=0; K<StrLen; K++)
{
for(unsigned L=0; L<26; L++)
{
if(LettersCopy[L])
{
LettersCopy[L]--;
unsigned Index=0;
for(unsigned I=0; !Index; I++)
{
if(CorrespondingNum==L)
Index=I+1;
}
Index--;
NumberString[K]=Index;
break;
}
}
}
}

// also define some sort of linked list or something //
// that can contain all of the strings //

unsigned NumPermutations=0;
bool Done=false;
while(!Done)
{
bool PermutationWorks=true;

unsigned LettersCopy[26];
for(unsigned CopyCounter=0; CopyCounter<26; CopyCounter++)
LettersCopy[CopyCounter]=Letters[CopyCounter];

char* Permutation=new char[StrLen+1];
for(unsigned K=0; K<StrLen; K++)
{
unsigned Letter=CorrespondingNum[NumberString[K]];
Permutation[K]='A'+Letter;
if(LettersCopy[Letter])
LettersCopy[Letter]--;
else PermutationWorks=false;
}
Permutation[StrLen]='\0';

if(PermutationWorks)
{
printf(Permutation);
printf("\n");
// Add Permutation to the linked list //;
NumPermutations++;
}
delete [] Permutation;

NumberString[StrLen-1]++;
for(unsigned L=StrLen-1; L; L--)
{
if(unsigned NextDigit=(NumberString[L]/NumDifferentLetters))
{
NumberString[L-1]+=NextDigit;
NumberString[L]%=NumDifferentLetters;
}
else goto EndOfLoop;
}
Done=(NumberString[0]/NumDifferentLetters);
EndOfLoop:;
}

delete [] NumberString;
delete [] CorrespondingNum;

return NumPermutations;
}

int main()
{
char String[MAX_LENGTH];
printf("Enter the word: ");
scanf("%s",String);
unsigned StrLen;
for(unsigned K=0; K<MAX_LENGTH; K++)
{
if(String[K]=='\0')
{
StrLen=K;
break;
}
}
printf("There are %d different permutations\n",FindPermutations(String, StrLen));
return 0;
}


This looks right...

Edit: I tested it, and it works now...

[Edited by - Nathaniel Hammen on September 21, 2004 9:05:20 PM]

Share this post


Link to post
Share on other sites
just a fast q ... trying hard to read your pyting code ( not a pytonist myself .. hehe )

how does your code deal with

ttss

just to make sure ... didn't quite understood the last while loop in the recusive ....

the test case is MISSISSIPPI ...

but my assignment have more to it, so there is more to be eliminated ... but those are more simpler to remove ( 3 or more of the same consonant "kkk", etc )

...but if duplicates are removed, the rest is childefood...

Share this post


Link to post
Share on other sites
results for ttss:

sstt
stst
stts
tsst
tsts
ttss

fine ?

oh, the last while loop is the point ;) it moves the i (index) to the next letter (not a duplicate of the current one)

btw, this algorithm should really perform better than the permutations-with-repetitions one :]

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!