import
java.util.ArrayList;
import
java.util.Collections;
import
java.util.List;
class
GFG {
static
String ans =
""
;
static
final
int
END = -
1
;
static
final
int
VALID =
1
;
static
void
printString(List<Integer> word, List<Pair<Character, Integer>> refList) {
StringBuilder str =
new
StringBuilder();
for
(
int
index : word) {
str.append(refList.get(index).first);
}
if
(str.length() !=
0
)
ans =
"\n"
+ str + ans;
}
static
boolean
hasConflict(List<Integer> word, List<Pair<Character, Integer>> refList,
int
index) {
if
(index >= word.size() || word.get(index) >= refList.size())
return
false
;
int
conflictCount =
0
;
for
(
int
i =
0
; i < index; i++) {
if
(word.get(i).equals(word.get(index)))
conflictCount++;
}
if
(conflictCount < refList.get(word.get(index)).second)
return
false
;
return
true
;
}
static
int
getNext(List<Integer> word, List<Pair<Character, Integer>> refList,
int
mod) {
int
left, right, carry;
right = word.size() -
1
;
carry =
1
;
for
(left = right; left >=
0
; left--) {
if
(left ==
0
&& word.get(left) + carry >= mod) {
return
END;
}
if
(word.get(left) + carry >= mod) {
word.set(left, (word.get(left) + carry) % mod);
}
else
{
word.set(left, word.get(left) + carry);
break
;
}
}
while
(left <= right) {
while
(hasConflict(word, refList, left) && word.get(left) < mod) {
word.set(left, word.get(left) +
1
);
}
if
(word.get(left) >= mod) {
word.set(left, word.get(left) % mod);
carry =
1
;
left--;
while
(left >=
0
) {
if
(left ==
0
&& word.get(left) + carry >= mod) {
return
END;
}
if
(word.get(left) + carry >= mod) {
word.set(left, (word.get(left) + carry) % mod);
left--;
}
else
{
word.set(left, word.get(left) + carry);
break
;
}
}
}
else
{
left++;
}
}
return
VALID;
}
static
void
generatePermutations(String str) {
if
(str.length() ==
0
)
return
;
char
[] charArray = str.toCharArray();
List<Character> charList =
new
ArrayList<>();
for
(
char
c : charArray) {
charList.add(c);
}
Collections.sort(charList, Collections.reverseOrder());
StringBuilder sortedStr =
new
StringBuilder();
for
(
char
c : charList) {
sortedStr.append(c);
}
List<Pair<Character, Integer>> refList =
new
ArrayList<>();
int
count =
0
;
refList.add(
new
Pair<>(sortedStr.charAt(
0
),
1
));
for
(
int
i =
1
; i < sortedStr.length(); i++) {
if
(sortedStr.charAt(i) == sortedStr.charAt(i -
1
)) {
refList.set(count,
new
Pair<>(refList.get(count).first, refList.get(count).second +
1
));
}
else
{
count++;
refList.add(
new
Pair<>(sortedStr.charAt(i),
1
));
}
}
while
(refList.size() > count +
1
) {
refList.remove(refList.size() -
1
);
}
while
(refList.size() < count +
1
) {
refList.add(
new
Pair<>(
'\0'
,
0
));
}
List<Integer> word =
new
ArrayList<>();
for
(
int
i =
0
; i < refList.size(); i++) {
for
(
int
j =
0
; j < refList.get(i).second; j++)
word.add(i);
}
int
mod = refList.size();
int
flag = VALID;
while
(flag != END) {
printString(word, refList);
flag = getNext(word, refList, mod);
}
System.out.println(ans);
}
public
static
void
main(String[] args) {
String str =
"abc"
;
generatePermutations(str);
}
static
class
Pair<A, B> {
A first;
B second;
public
Pair(A first, B second) {
this
.first = first;
this
.second = second;
}
}
}