Recursively creating strings from 2 dimensional character array - java

I need to create all possible strings from a 2d-array so that the first character comes from charArray[0], the second character comes from charArray[1]...and the final character comes from the charArray[keyLength-1].
Example:
input:
char[][] charArray =
{{'m','M','L','S','X'}
{'e','E','o','N','Z'}
{'o','G','F','r','Y'}
{'D','H','I','J','w'}};
output:
{meoD, meoH, meoI,..., XZYJ, XZYw} //in an Array or ArrayList
I had a working solution that builts a tree with each character in charArray[0] as a root and it did a depth first string construction, but the JVM ran out of memory for charArray lengths less than 12. I would normally take an iterative approach, but the charArray length (i.e. key string length) is decided at runtime and I would like to find a more complete solution than writing a switch statement on the key string length and manually writing out loops for a finite number of key string lengths.
I've been stuck on this small section of my program for longer than I'd like to admit, so any help would be greatly appreciated!

Here is how it can be solved:
import java.util.ArrayList;
import java.util.List;
public class Arrays2D {
public static void main(String[] args) {
//input keys
String[][] charArray =
{{"m","M","L","S","X"},
{"e","E","o","N","Z"},
{"o","G","F","r","Y"},
{"D","H","I","J","w"}};
//print output
System.out.println(findCombinations(charArray));
}
private static List<String> findCombinations(String[][] charArray) {
List<String> prev = null;
for (int i = 0; i < charArray.length; i++) {
List<String> curr = new ArrayList<String>();
for (int j = 0; j < charArray[i].length; j++) {
if (i + 1 < charArray.length) {
for (int l = 0; l < charArray[i+1].length; l++) {
String s = charArray[i][j] + charArray[i + 1][l];
curr.add(s);
}
}
}
if (prev != null && !curr.isEmpty()) {
prev = join(prev, curr);
}
if (prev == null)
prev = curr;
}
return prev;
}
public static List<String> join(List<String> p, List<String> q) {
List<String> join = new ArrayList<String>();
for (String st1 : p) {
for (String st2 : q) {
if (st1.substring(st1.length() - 1).equals(st2.substring(0, 1))) {
String s = st1 + st2;
s = s.replaceFirst(st1.substring(st1.length() - 1), "");
join.add(s);
}
}
}
return join;
}
}
I have checked and it correctly generating the combinations. You can run and see the output.

Related

Common characters in n strings

I m trying to make a function that prints the number of characters common in given n strings. (note that characters may be used multiple times)
I am struggling to perform this operation on n strings However I did it for 2 strings without any characters repeated more than once.
I have posted my code.
public class CommonChars {
public static void main(String[] args) {
String str1 = "abcd";
String str2 = "bcde";
StringBuffer sb = new StringBuffer();
// get unique chars from both the strings
str1 = uniqueChar(str1);
str2 = uniqueChar(str2);
int count = 0;
int str1Len = str1.length();
int str2Len = str2.length();
for (int i = 0; i < str1Len; i++) {
for (int j = 0; j < str2Len; j++) {
// found match stop the loop
if (str1.charAt(i) == str2.charAt(j)) {
count++;
sb.append(str1.charAt(i));
break;
}
}
}
System.out.println("Common Chars Count : " + count + "\nCommon Chars :" +
sb.toString());
}
public static String uniqueChar(String inputString) {
String outputstr="",temp="";
for(int i=0;i<inputstr.length();i++) {
if(temp.indexOf(inputstr.charAt(i))<0) {
temp+=inputstr.charAt(i);
}
}
System.out.println("completed");
return temp;
}
}
3
abcaa
bcbd
bgc
3
their may be chances that a same character can be present multiple times in
a string and you are not supposed to eliminate those characters instead
check the no. of times they are repeated in other strings. for eg
3
abacd
aaxyz
aatre
output should be 2
it will be better if i get solution in java
You have to convert all Strings to Set of Characters and retain all from the first one. Below solution has many places which could be optimised but you should understand general idea.
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
public class Main {
public static void main(String[] args) {
List<String> input = Arrays.asList("jonas", "ton", "bonny");
System.out.println(findCommonCharsFor(input));
}
public static Collection<Character> findCommonCharsFor(List<String> strings) {
if (strings == null || strings.isEmpty()) {
return Collections.emptyList();
}
Set<Character> commonChars = convertStringToSetOfChars(strings.get(0));
strings.stream().skip(1).forEach(s -> commonChars.retainAll(convertStringToSetOfChars(s)));
return commonChars;
}
private static Set<Character> convertStringToSetOfChars(String string) {
if (string == null || string.isEmpty()) {
return Collections.emptySet();
}
Set<Character> set = new HashSet<>(string.length() + 10);
for (char c : string.toCharArray()) {
set.add(c);
}
return set;
}
}
Above code prints:
[n, o]
A better strategy for your problem is to use this method:
public int[] countChars(String s){
int[] count = new int[26];
for(char c: s.toCharArray()){
count[c-'a']++;
}
return count;
}
Now if you have n Strings (String[] strings) just find the min of common chars for each letter:
int[][] result = new int[n][26]
for(int i = 0; i<strings.length;i++){
result[i] = countChars(s);
}
// now if you sum the min common chars for each counter you are ready
int commonChars = 0;
for(int i = 0; i< 26;i++){
int min = result[0][i];
for(int i = 1; i< n;i++){
if(min>result[j][i]){
min = result[j][i];
}
}
commonChars+=min;
}
Get list of characters for each string:
List<Character> chars1 = s1.chars() // list of chars for first string
.mapToObj(c -> (char) c)
.collect(Collectors.toList());
List<Character> chars2 = s2.chars() // list of chars for second string
.mapToObj(c -> (char) c)
.collect(Collectors.toList());
Then use retainAll method:
chars1.retainAll(chars2); // retain in chars1 only the chars that are contained in the chars2 also
System.out.println(chars1.size());
If you want to get number of unique chars just use Collectors.toSet() instead of toList()
Well if one goes for hashing:
public static int uniqueChars(String first, String second) {
boolean[] hash = new boolean[26];
int count = 0;
//reduce first string to unique letters
for (char c : first.toLowerCase().toCharArray()) {
hash[c - 'a'] = true;
}
//reduce to unique letters in both strings
for(char c : second.toLowerCase().toCharArray()){
if(hash[c - 'a']){
count++;
hash[c - 'a'] = false;
}
}
return count;
}
This is using bucketsort which gives a n+m complexity but needs the 26 buckets(the "hash" array).
Imo one can't do better in regards of complexity as you need to look at every letter at least once which sums up to n+m.
Insitu the best you can get is imho somewhere in the range of O(n log(n) ) .
Your aproach is somewhere in the league of O(n²)
Addon: if you need the characters as a String(in essence the same as above with count is the length of the String returned):
public static String uniqueChars(String first, String second) {
boolean[] hash = new boolean[26];
StringBuilder sb = new StringBuilder();
for (char c : first.toLowerCase().toCharArray()) {
hash[c - 'a'] = true;
}
for(char c : second.toLowerCase().toCharArray()){
if(hash[c - 'a']){
sb.append(c);
hash[c - 'a'] = false;
}
}
return sb.toString();
}
public static String getCommonCharacters(String... words) {
if (words == null || words.length == 0)
return "";
Set<Character> unique = words[0].chars().mapToObj(ch -> (char)ch).collect(Collectors.toCollection(TreeSet::new));
for (String word : words)
unique.retainAll(word.chars().mapToObj(ch -> (char)ch).collect(Collectors.toSet()));
return unique.stream().map(String::valueOf).collect(Collectors.joining());
}
Another variant without creating temporary Set and using Character.
public static String getCommonCharacters(String... words) {
if (words == null || words.length == 0)
return "";
int[] arr = new int[26];
boolean[] tmp = new boolean[26];
for (String word : words) {
Arrays.fill(tmp, false);
for (int i = 0; i < word.length(); i++) {
int pos = Character.toLowerCase(word.charAt(i)) - 'a';
if (tmp[pos])
continue;
tmp[pos] = true;
arr[pos]++;
}
}
StringBuilder buf = new StringBuilder(26);
for (int i = 0; i < arr.length; i++)
if (arr[i] == words.length)
buf.append((char)('a' + i));
return buf.toString();
}
Demo
System.out.println(getCommonCharacters("abcd", "bcde")); // bcd

Adding Values to a LinkedList Not Working

I am trying to do a programming problem a day on leetcode to improve my programming and am having issues adding to a LinkedList in the problem below. I was wondering if anyone could give me some pointers. I know my answer isn't the most efficient, I just wanted to start somewhere and work myself up. Everything within the method is stuff I did so far. I really appreciate any help.
///
You are given two non-empty linked lists representing two non-negative integers. The digits are stored in reverse order and each of their nodes contain a single digit. Add the two numbers and return it as a linked list.
Here's a picture with an example for a possible output:
https://imgur.com/a/g9rlb
You may assume the two numbers do not contain any leading zero, except the number 0 itself.
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
ListNode l3 = new ListNode(-1);
ListNode curr = new ListNode(-1);
ListNode newNode = new ListNode(-1);
// Take numbers from linkedList and store in strings
String s1 = "";
String s2 = "";
// String values after being reveresed in the right direction.
String sR1 = "";
String sR2 = "";
while(l1 != null) {
s1 += l1.val;
l1 = l1.next;
}
while(l2 != null) {
s2 += l2.val;
l2 = l2.next;
}
//check
System.out.println(s1);
System.out.println(s2);
//reverse the string;
for(int i = s1.length()-1; i >= 0; i--) {
sR1 += s1.charAt(i);
}
for(int j = s2.length()-1; j >= 0; j--) {
sR2 += s2.charAt(j);
}
//Adding the numbers together to get the final value.
int n3 = Integer.parseInt(sR1) + Integer.parseInt(sR2);
//Converting ints to string so i can parse them into characters that will eventually be parsed into an int to return back to the LinkedList
String fin = Integer.toString(n3);
System.out.println(fin);
//adding the values to my final linked list that i'd be returning here. This is the part that isn't working.
for(int i = 0; i < fin.length()-1; i++){
String s = String.valueOf(fin.charAt(i));
int num = Integer.parseInt(s);
newNode = new ListNode(num);
if(l3.val == -1) {
l3 = newNode;
}
else {
curr = l3;
while(curr.next != null){
curr = curr.next;
}
curr.val = num;
}
}
return l3;
}
Maybe something like this? The concept here is straight forward.
The requirement is to reverse the nodes and adding them. Which means you just need to choose the right data structure to meet this requirement, which provides you last in first out? Stack. Now that you have you data in a stack just pop the items from the stack and add it up and get your expected result.
There are many ways to solve this, Using an ArrayList, using LinkedList, or plain old arrays, but try to correlate the problem with a known data structure and addressing it that way would give you meaningful output consistently. I could have just pointed you to the concept but having this code will help you think on how to address a specific problem based on the user requirement. Cheers, hope it helps.
import java.util.Scanner;
import java.util.Stack;
public class AddTuple {
public static void main(String[] args) {
Stack<Integer> leftTuple = new Stack<Integer>();
Stack<Integer> rightTuple = new Stack<Integer>();
populateTuple(leftTuple, rightTuple, 3);
Stack<Integer> result = addTuples(leftTuple, rightTuple);
System.out.print("Output: {");
int i = 0;
while (!result.isEmpty()) {
if (i != 0) {
System.out.print(", ");
}
System.out.print(result.pop());
i++;
}
System.out.println("}");
}
private static void populateTuple(Stack<Integer> leftTuple, Stack<Integer> rightTuple, int count) {
Scanner scanner = new Scanner(System.in);
try {
System.out.print("Input: ");
String input = scanner.nextLine();
if (input == null || !input.contains("+") || !input.contains("{")) {
throw new RuntimeException("Usage: {x,y,z} + {a,b,c}");
}
String[] operandSplit = input.split("\\+");
String left = operandSplit[0].trim();
String right = operandSplit[1].trim();
left = left.replaceAll("\\{", "");
left = left.replaceAll("\\}", "");
right = right.replaceAll("\\{", "");
right = right.replaceAll("\\}", "");
String[] leftSplit = left.split(",");
String[] rightSplit = right.split(",");
for (int i = 0; i < leftSplit.length; i++) {
leftTuple.push(Integer.parseInt(leftSplit[i].trim()));
}
for (int i = 0; i < rightSplit.length; i++) {
rightTuple.push(Integer.parseInt(rightSplit[i].trim()));
}
} finally {
scanner.close();
}
}
private static Stack<Integer> addTuples(Stack<Integer> leftTuple, Stack<Integer> rightTuple) {
Stack<Integer> result = new Stack<Integer>();
int carryForward = 0;
while (!leftTuple.isEmpty()) {
int addition = leftTuple.pop() + rightTuple.pop() + carryForward;
if (addition > 9) {
carryForward = 1;
addition = 10 - addition;
}
result.push(addition);
}
return result;
}
}

permutations of a string using iteration

I'm trying to find permutation of a given string, but I want to use iteration. The recursive solution I found online and I do understand it, but converting it to an iterative solution is really not working out. Below I have attached my code. I would really appreciate the help:
public static void combString(String s) {
char[] a = new char[s.length()];
//String temp = "";
for(int i = 0; i < s.length(); i++) {
a[i] = s.charAt(i);
}
for(int i = 0; i < s.length(); i++) {
String temp = "" + a[i];
for(int j = 0; j < s.length();j++) {
//int k = j;
if(i != j) {
System.out.println(j);
temp += s.substring(0,j) + s.substring(j+1,s.length());
}
}
System.out.println(temp);
}
}
Following up on my related question comment, here's a Java implementation that does what you want using the Counting QuickPerm Algorithm:
public static void combString(String s) {
// Print initial string, as only the alterations will be printed later
System.out.println(s);
char[] a = s.toCharArray();
int n = a.length;
int[] p = new int[n]; // Weight index control array initially all zeros. Of course, same size of the char array.
int i = 1; //Upper bound index. i.e: if string is "abc" then index i could be at "c"
while (i < n) {
if (p[i] < i) { //if the weight index is bigger or the same it means that we have already switched between these i,j (one iteration before).
int j = ((i % 2) == 0) ? 0 : p[i];//Lower bound index. i.e: if string is "abc" then j index will always be 0.
swap(a, i, j);
// Print current
System.out.println(join(a));
p[i]++; //Adding 1 to the specific weight that relates to the char array.
i = 1; //if i was 2 (for example), after the swap we now need to swap for i=1
}
else {
p[i] = 0;//Weight index will be zero because one iteration before, it was 1 (for example) to indicate that char array a[i] swapped.
i++;//i index will have the option to go forward in the char array for "longer swaps"
}
}
}
private static String join(char[] a) {
StringBuilder builder = new StringBuilder();
builder.append(a);
return builder.toString();
}
private static void swap(char[] a, int i, int j) {
char temp = a[i];
a[i] = a[j];
a[j] = temp;
}
List<String> results = new ArrayList<String>();
String test_str = "abcd";
char[] chars = test_str.toCharArray();
results.add(new String("" + chars[0]));
for(int j=1; j<chars.length; j++) {
char c = chars[j];
int cur_size = results.size();
//create new permutations combing char 'c' with each of the existing permutations
for(int i=cur_size-1; i>=0; i--) {
String str = results.remove(i);
for(int l=0; l<=str.length(); l++) {
results.add(str.substring(0,l) + c + str.substring(l));
}
}
}
System.out.println("Number of Permutations: " + results.size());
System.out.println(results);
Example:
if we have 3 character string e.g. "abc", we can form permuations as below.
1) construct a string with first character e.g. 'a' and store that in results.
char[] chars = test_str.toCharArray();
results.add(new String("" + chars[0]));
2) Now take next character in string (i.e. 'b') and insert that in all possible positions of previously contsructed strings in results. Since we have only one string in results ("a") at this point, doing so gives us 2 new strings 'ba', 'ab'. Insert these newly constructed strings in results and remove "a".
for(int i=cur_size-1; i>=0; i--) {
String str = results.remove(i);
for(int l=0; l<=str.length(); l++) {
results.add(str.substring(0,l) + c + str.substring(l));
}
}
3) Repeat 2) for every character in the given string.
for(int j=1; j<chars.length; j++) {
char c = chars[j];
....
....
}
This gives us "cba", "bca", "bac" from "ba" and "cab", "acb" and "abc" from "ab"
Work queue allows us to create an elegant iterative solution for this problem.
static List<String> permutations(String string) {
List<String> permutations = new LinkedList<>();
Deque<WorkUnit> workQueue = new LinkedList<>();
// We need to permutate the whole string and haven't done anything yet.
workQueue.add(new WorkUnit(string, ""));
while (!workQueue.isEmpty()) { // Do we still have any work?
WorkUnit work = workQueue.poll();
// Permutate each character.
for (int i = 0; i < work.todo.length(); i++) {
String permutation = work.done + work.todo.charAt(i);
// Did we already build a complete permutation?
if (permutation.length() == string.length()) {
permutations.add(permutation);
} else {
// Otherwise what characters are left?
String stillTodo = work.todo.substring(0, i) + work.todo.substring(i + 1);
workQueue.add(new WorkUnit(stillTodo, permutation));
}
}
}
return permutations;
}
A helper class to hold partial results is very simple.
/**
* Immutable unit of work
*/
class WorkUnit {
final String todo;
final String done;
WorkUnit(String todo, String done) {
this.todo = todo;
this.done = done;
}
}
You can test the above piece of code by wrapping them in this class.
import java.util.*;
public class AllPermutations {
public static void main(String... args) {
String str = args[0];
System.out.println(permutations(str));
}
static List<String> permutations(String string) {
...
}
}
class WorkUnit {
...
}
Try it by compiling and running.
$ javac AllPermutations.java; java AllPermutations abcd
The below implementation can also be easily tweaked to return a list of permutations in reverse order by using a LIFO stack of work instead of a FIFO queue.
import java.util.List;
import java.util.Set;
import java.util.ArrayList;
import java.util.HashSet;
public class Anagrams{
public static void main(String[] args)
{
String inpString = "abcd";
Set<String> combs = getAllCombs(inpString);
for(String comb : combs)
{
System.out.println(comb);
}
}
private static Set<String> getAllCombs(String inpString)
{
Set<String> combs = new HashSet<String>();
if( inpString == null | inpString.isEmpty())
return combs;
combs.add(inpString.substring(0,1));
Set<String> tempCombs = new HashSet<String>();
for(char a : inpString.substring(1).toCharArray())
{
tempCombs.clear();
tempCombs.addAll(combs);
combs.clear();
for(String comb : tempCombs)
{
combs.addAll(getCombs(comb,a));
}
}
return combs;
}
private static Set<String> getCombs(String comb, char a) {
Set<String> combs = new HashSet<String>();
for(int i = 0 ; i <= comb.length(); i++)
{
String temp = comb.substring(0, i) + a + comb.substring(i);
combs.add(temp);
//System.out.println(temp);
}
return combs;
}
}
Just posting my approach to the problem:
import java.util.ArrayDeque;
import java.util.Queue;
public class PermutationIterative {
public static void main(String[] args) {
permutationIterative("abcd");
}
private static void permutationIterative(String str) {
Queue<String> currentQueue = null;
int charNumber = 1;
for (char c : str.toCharArray()) {
if (currentQueue == null) {
currentQueue = new ArrayDeque<>(1);
currentQueue.add(String.valueOf(c));
} else {
int currentQueueSize = currentQueue.size();
int numElements = currentQueueSize * charNumber;
Queue<String> nextQueue = new ArrayDeque<>(numElements);
for (int i = 0; i < currentQueueSize; i++) {
String tempString = currentQueue.remove();
for (int j = 0; j < charNumber; j++) {
int n = tempString.length();
nextQueue.add(tempString.substring(0, j) + c + tempString.substring(j, n));
}
}
currentQueue = nextQueue;
}
charNumber++;
}
System.out.println(currentQueue);
}
}
package vishal villa;
import java.util.Scanner;
public class Permutation {
static void result( String st, String ans)
{
if(st.length() == 0)
System.out.println(ans +" ");
for(int i = 0; i<st.length(); i++)
{
char ch = st.charAt(i);
String r = st.substring(0, i) + st.substring(i + 1);
result(r, ans + ch);
}
}
public static void main(String[] args)
{
Scanner Sc = new Scanner(System.in);
System.out.println("enter the string");
String st = Sc.nextLine();
Permutation p = new Permutation();
p.result(st,"" );
}
}
// Java program to print all permutations of a
// given string.
public class Permutation
{
public static void main(String[] args)
{
String str = "ABC";
int n = str.length();
Permutation permutation = new Permutation();
permutation.permute(str, 0, n-1);
}
/**
* permutation function
* #param str string to calculate permutation for
* #param s starting index
* #param e end index
*/
private void permute(String str, int s, int e)
{
if (s == e)
System.out.println(str);
else
{
for (int i = s; i <= s; i++)
{
str = swap(str,l,i);
permute(str, s+1, e);
str = swap(str,l,i);
}
}
}
/**
* Swap Characters at position
* #param a string value
* #param i position 1
* #param j position 2
* #return swapped string
*/
public String swap(String a, int i, int j)
{
char temp;
char[] charArray = a.toCharArray();
temp = charArray[i] ;
charArray[i] = charArray[j];
charArray[j] = temp;
return String.valueOf(charArray);
}
}

Finding a word on a two dimensional char array

What kind of approch could be an easy way to find the given words on a puzzle like this? I'm using Java. Thanks for help.
Interesting question. I would solve this by first building a list of "possible word holders" (sequences of characters which can possibly hold one of the given words) by traversing the puzzle horizontally, vertically and diagonally (in both directions). I would then see if the given words (or their reverse) are present (using contains() method in Java) in each of the obtained "possible word holders". Here is the code I wrote in Java. I haven't tested it properly, but I guess it works!
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.Set;
public class WordPuzzle {
public Set<String> findWords(char[][] puzzle, Set<String> words) {
Set<String> foundWords = new HashSet<String>();
int minimumWordLength = findMinimumWordLength(words);
Set<String> possibleWords = findPossibleWords(puzzle, minimumWordLength);
for(String word : words) {
for(String possibleWord : possibleWords) {
if(possibleWord.contains(word) || possibleWord.contains(new StringBuffer(word).reverse())) {
foundWords.add(word);
break;
}
}
}
return foundWords;
}
private int findMinimumWordLength(Set<String> words) {
int minimumLength = Integer.MAX_VALUE;
for(String word : words) {
if(word.length() < minimumLength)
minimumLength = word.length();
}
return minimumLength;
}
private Set<String> findPossibleWords(char[][] puzzle, int minimumWordLength) {
Set<String> possibleWords = new LinkedHashSet<String>();
int dimension = puzzle.length; //Assuming puzzle is square
if(dimension >= minimumWordLength) {
/* Every row in the puzzle is added as a possible word holder */
for(int i = 0; i < dimension; i++) {
if(puzzle[i].length >= minimumWordLength) {
possibleWords.add(new String(puzzle[i]));
}
}
/* Every column in the puzzle is added as a possible word holder */
for(int i = 0; i < dimension; i++) {
StringBuffer temp = new StringBuffer();
for(int j = 0; j < dimension; j++) {
temp = temp.append(puzzle[j][i]);
}
possibleWords.add(new String(temp));
}
/* Adding principle diagonal word holders */
StringBuffer temp1 = new StringBuffer();
StringBuffer temp2 = new StringBuffer();
for(int i = 0; i < dimension; i++) {
temp1 = temp1.append(puzzle[i][i]);
temp2 = temp2.append(puzzle[i][dimension - i - 1]);
}
possibleWords.add(new String(temp1));
possibleWords.add(new String(temp2));
/* Adding non-principle diagonal word holders */
for(int i = 1; i < dimension - minimumWordLength; i++) {
temp1 = new StringBuffer();
temp2 = new StringBuffer();
StringBuffer temp3 = new StringBuffer();
StringBuffer temp4 = new StringBuffer();
for(int j = i, k = 0; j < dimension && k < dimension; j++, k++) {
temp1 = temp1.append(puzzle[j][k]);
temp2 = temp2.append(puzzle[k][j]);
temp3 = temp3.append(puzzle[dimension - j - 1][k]);
temp4 = temp4.append(puzzle[dimension - k - 1][j]);
}
possibleWords.add(new String(temp1));
possibleWords.add(new String(temp2));
possibleWords.add(new String(temp3));
possibleWords.add(new String(temp4));
}
}
return possibleWords;
}
public static void main(String args[]) {
WordPuzzle program = new WordPuzzle();
char[][] puzzle = {
{'F','Y','Y','H','N','R','D'},
{'R','L','J','C','I','N','U'},
{'A','A','W','A','A','H','R'},
{'N','T','K','L','P','N','E'},
{'C','I','L','F','S','A','P'},
{'E','O','G','O','T','P','N'},
{'H','P','O','L','A','N','D'}
};
Set<String> words = new HashSet<String>();
words.add("FRANCE");
words.add("POLAND");
words.add("INDIA");
words.add("JAPAN");
words.add("USA");
words.add("HOLLAND");
Set<String> wordsFound = program.findWords(puzzle, words);
for(String word : wordsFound) {
System.out.println(word);
}
}
}
In general, I say use the most naive approach unless your puzzles are going to be large. I wouldn't optimize anything that takes less than 0.1s, but thats just me.
foreach box
for all directions
grab the string of characters in that direction
lookup a dictionary
I think the smarts can be in how you design your dictionary. In this case, I would do a multi-level hash table where characters pick which hash table to look at the next level.
I would put the word list into a Trie, then do a search from all squares in all directions.
The easiest approach (conceptualy) is to simply enumerate all possible words in your array and check all of then in a dictionnary. A dictionnary behing a map, an array of string... or a real dictionnary downloaded from the internet.
As an exemple here is the code to find all possible word horizontally... Adding other direction is just more work :
import java.util.HashSet;
import java.util.Set;
public class WordFinder {
public static void main(String[] args) {
String[][] words = { { "F", "Y", "Y", "H", "N", "R", "D" },
{ "R", "L", "J", "C", "I", "N", "U" },
...};
Set<String> dictionnary = new HashSet<String>();
dictionnary.add(...);
Set<String> wordsFound = findWords(words, dictionnary);
...
}
/**
* Find all words in the specified array present in the dictionnary.
*
*/
private static Set<String> findWords(String[][] words, Set<String> dictionnary) {
Set<String> wordsFound = new HashSet<String>();
// Find all possible words horizontally :
int nbrRows = words.length;
int nbrCol = words[0].length; // We suppose we have at least one row and all row have same lengh
// Iterate through all rows
for (int currentRow = 0; currentRow < nbrRows; currentRow++) {
// Iterate through all possible starting position in the current row.
for (int beginWordIndex = 0; beginWordIndex < nbrCol; beginWordIndex++) {
// Iterate then through all possible ending positions in the current row, so to deal with word of any lengh.
for (int endWordIndex = beginWordIndex; endWordIndex < nbrCol; endWordIndex++) {
// Construct a word from the begin/end indexes :
String currentWord = getWordInRow(words, currentRow, beginWordIndex, endWordIndex);
// Check if the word candidate really exist, if yes, store it in the wordsFound variable.
if (dictionnary.contains(currentWord)) {
wordsFound.add(currentWord);
}
// The reverse
String reverseWord = reverseString(currentWord);
// Check if the reverse word really exist, if yes, store it in the wordsFound variable.
if (dictionnary.contains(reverseWord)) {
wordsFound.add(currentWord);
}
}
}
}
// Don't forget vertically and in diagonals too... Same principe.
return wordsFound;
}
/**
* Return a word "candidate" in the specified row, starting at beginIndex and finishing at endIndex.
*/
private static String getWordInRow(String[][] words, int row, int beginIndex, int endIndex) {
String currentWord = "";
int currentPosition = beginIndex;
while (currentPosition <= endIndex) {
currentWord += words[row][currentPosition];
}
return currentWord;
}
/**
* Return the reverse of a String
*/
private static String reverseString(String string) {
String result = "";
for (int i = string.length()-1; i >=0;i++) {
result+= string.charAt(i);
}
return result;
}
}
This is not the best, most effective solution. But it is conceptually simple.
EDIT :
reverse order: see edited code. Just write a function that can reverse a word. Because we already have all posible word in normal order, reversing them is enough to have words in reverse order.
Diagonals : I'am sure you can do it if you have understood the code I have already put. I will not do your homework or do your testing in place of you. Try to figure how you would do it with a paper and a pen. How would you do it if you had to do it by hand. Then from that, write your solution ;)

function to remove duplicate characters in a string

The following code is trying to remove any duplicate characters in a string. I'm not sure if the code is right. Can anybody help me work with the code (i.e whats actually happening when there is a match in characters)?
public static void removeDuplicates(char[] str) {
if (str == null) return;
int len = str.length;
if (len < 2) return;
int tail = 1;
for (int i = 1; i < len; ++i) {
int j;
for (j = 0; j < tail; ++j) {
if (str[i] == str[j]) break;
}
if (j == tail) {
str[tail] = str[i];
++tail;
}
}
str[tail] = 0;
}
The function looks fine to me. I've written inline comments. Hope it helps:
// function takes a char array as input.
// modifies it to remove duplicates and adds a 0 to mark the end
// of the unique chars in the array.
public static void removeDuplicates(char[] str) {
if (str == null) return; // if the array does not exist..nothing to do return.
int len = str.length; // get the array length.
if (len < 2) return; // if its less than 2..can't have duplicates..return.
int tail = 1; // number of unique char in the array.
// start at 2nd char and go till the end of the array.
for (int i = 1; i < len; ++i) {
int j;
// for every char in outer loop check if that char is already seen.
// char in [0,tail) are all unique.
for (j = 0; j < tail; ++j) {
if (str[i] == str[j]) break; // break if we find duplicate.
}
// if j reachs tail..we did not break, which implies this char at pos i
// is not a duplicate. So we need to add it our "unique char list"
// we add it to the end, that is at pos tail.
if (j == tail) {
str[tail] = str[i]; // add
++tail; // increment tail...[0,tail) is still "unique char list"
}
}
str[tail] = 0; // add a 0 at the end to mark the end of the unique char.
}
Your code is, I'm sorry to say, very C-like.
A Java String is not a char[]. You say you want to remove duplicates from a String, but you take a char[] instead.
Is this char[] \0-terminated? Doesn't look like it because you take the whole .length of the array. But then your algorithm tries to \0-terminate a portion of the array. What happens if the arrays contains no duplicates?
Well, as it is written, your code actually throws an ArrayIndexOutOfBoundsException on the last line! There is no room for the \0 because all slots are used up!
You can add a check not to add \0 in this exceptional case, but then how are you planning to use this code anyway? Are you planning to have a strlen-like function to find the first \0 in the array? And what happens if there isn't any? (due to all-unique exceptional case above?).
What happens if the original String/char[] contains a \0? (which is perfectly legal in Java, by the way, see JLS 10.9 An Array of Characters is Not a String)
The result will be a mess, and all because you want to do everything C-like, and in place without any additional buffer. Are you sure you really need to do this? Why not work with String, indexOf, lastIndexOf, replace, and all the higher-level API of String? Is it provably too slow, or do you only suspect that it is?
"Premature optimization is the root of all evils". I'm sorry but if you can't even understand what the original code does, then figuring out how it will fit in the bigger (and messier) system will be a nightmare.
My minimal suggestion is to do the following:
Make the function takes and returns a String, i.e. public static String removeDuplicates(String in)
Internally, works with char[] str = in.toCharArray();
Replace the last line by return new String(str, 0, tail);
This does use additional buffers, but at least the interface to the rest of the system is much cleaner.
Alternatively, you can use StringBuilder as such:
static String removeDuplicates(String s) {
StringBuilder noDupes = new StringBuilder();
for (int i = 0; i < s.length(); i++) {
String si = s.substring(i, i + 1);
if (noDupes.indexOf(si) == -1) {
noDupes.append(si);
}
}
return noDupes.toString();
}
Note that this is essentially the same algorithm as what you had, but much cleaner and without as many little corner cases, etc.
Given the following question :
Write code to remove the duplicate characters in a string without
using any additional buffer. NOTE: One or two additional variables
are fine. An extra copy of the array is not.
Since one or two additional variables are fine but no buffer is allowed, you can simulate the behaviour of a hashmap by using an integer to store bits instead. This simple solution runs at O(n), which is faster than yours. Also, it isn't conceptually complicated and in-place :
public static void removeDuplicates(char[] str) {
int map = 0;
for (int i = 0; i < str.length; i++) {
if ((map & (1 << (str[i] - 'a'))) > 0) // duplicate detected
str[i] = 0;
else // add unique char as a bit '1' to the map
map |= 1 << (str[i] - 'a');
}
}
The drawback is that the duplicates (which are replaced with 0's) will not be placed at the end of the str[] array. However, this can easily be fixed by looping through the array one last time. Also, an integer has the capacity for only regular letters.
private static String removeDuplicateCharactersFromWord(String word) {
String result = new String("");
for (int i = 0; i < word.length(); i++) {
if (!result.contains("" + word.charAt(i))) {
result += "" + word.charAt(i);
}
}
return result;
}
This is my solution.
The algorithm is mainly the same as the one in the book "Cracking the code interview" where this exercise comes from, but I tried to improve it a bit and make the code more understandable:
public static void removeDuplicates(char[] str) {
// if string has less than 2 characters, it can't contain
// duplicate values, so there's nothing to do
if (str == null || str.length < 2) {
return;
}
// variable which indicates the end of the part of the string
// which is 'cleaned' (all duplicates removed)
int tail = 0;
for (int i = 0; i < str.length; i++) {
boolean found = false;
// check if character is already present in
// the part of the array before the current char
for (int j = 0; j < i; j++) {
if (str[j] == str[i]) {
found = true;
break;
}
}
// if char is already present
// skip this one and do not copy it
if (found) {
continue;
}
// copy the current char to the index
// after the last known unique char in the array
str[tail] = str[i];
tail++;
}
str[tail] = '\0';
}
One of the important requirements from the book is to do it in-place (as in my solution), which means that no additional data structure should be used as a helper while processing the string. This improves performance by not wasting memory unnecessarily.
char[] chars = s.toCharArray();
HashSet<Character> charz = new HashSet<Character>();
for(Character c : s.toCharArray() )
{
if(!charz.contains(c))
{
charz.add(c);
//System.out.print(c);
}
}
for(Character c : charz)
{
System.out.print(c);
}
public String removeDuplicateChar(String nonUniqueString) {
String uniqueString = "";
for (char currentChar : nonUniqueString.toCharArray()) {
if (!uniqueString.contains("" + currentChar)) {
uniqueString += currentChar;
}
}
return uniqueString;
}
public static void main (String [] args)
{
String s = "aabbbeeddsfre";//sample string
String temp2="";//string with no duplicates
HashMap<Integer,Character> tc = new HashMap<Integer,Character>();//create a hashmap to store the char's
char [] charArray = s.toCharArray();
for (Character c : charArray)//for each char
{
if (!tc.containsValue(c))//if the char is not already in the hashmap
{
temp2=temp2+c.toString();//add the char to the output string
tc.put(c.hashCode(),c);//and add the char to the hashmap
}
}
System.out.println(temp2);//final string
}
instead of HashMap I think we can use Set too.
I understand that this is a Java question, but since I have a nice solution which could inspire someone to convert this into Java, by all means. Also I like answers where multiple language submissions are available to common problems.
So here is a Python solution which is O(n) and also supports the whole ASCII range. Of course it does not treat 'a' and 'A' as the same:
I am using 8 x 32 bits as the hashmap:
Also input is a string array using dedup(list('some string'))
def dedup(str):
map = [0,0,0,0,0,0,0,0]
for i in range(len(str)):
ascii = ord(str[i])
slot = ascii / 32
bit = ascii % 32
bitOn = map[slot] & (1 << bit)
if bitOn:
str[i] = ''
else:
map[slot] |= 1 << bit
return ''.join(str)
also a more pythonian way to do this is by using a set:
def dedup(s):
return ''.join(list(set(s)))
Substringing method. Concatenation is done with .concat() to avoid allocation additional memory for left hand and right hand of +.
Note: This removes even duplicate spaces.
private static String withoutDuplicatesSubstringing(String s){
for(int i = 0; i < s.length(); i++){
String sub = s.substring(i+1);
int index = -1;
while((index = sub.toLowerCase().indexOf(Character.toLowerCase(s.charAt(i)))) > -1 && !sub.isEmpty()){
sub = sub.substring(0, index).concat(sub.substring(index+1, sub.length()));
}
s = s.substring(0, i+1).concat(sub);
}
return s;
}
Test case:
String testCase1 = "nanananaa! baaaaatmaan! batman!";
Output:
na! btm
Question: Remove Duplicate characters in a string
Method 1 :(Python)
import collections
a = "GiniGinaProtijayi"
aa = collections.OrderedDict().fromkeys(a)
print(''.join(aa))
Method 2 :(Python)
a = "GiniGinaProtijayi"
list = []
aa = [ list.append(ch) for ch in a if ch not in list]
print( ''.join(list))
IN Java:
class test2{
public static void main(String[] args) {
String a = "GiniGinaProtijayi";
List<Character> list = new ArrayList<>();
for(int i = 0 ; i < a.length() ;i++) {
char ch = a.charAt(i);
if( list.size() == 0 ) {list.add(ch);}
if(!list.contains(ch)) {list.add(ch) ;}
}//for
StringBuffer sbr = new StringBuffer();
for( char ch : list) {sbr.append(ch);}
System.out.println(sbr);
}//main
}//end
This would be much easier if you just looped through the array and added all new characters to a list, then retruned that list.
With this approach, you need to reshuffle the array as you step through it and eventually redimension it to the appropriate size in the end.
String s = "Javajk";
List<Character> charz = new ArrayList<Character>();
for (Character c : s.toCharArray()) {
if (!(charz.contains(Character.toUpperCase(c)) || charz
.contains(Character.toLowerCase(c)))) {
charz.add(c);
}
}
ListIterator litr = charz.listIterator();
while (litr.hasNext()) {
Object element = litr.next();
System.err.println(":" + element);
} }
this will remove the duplicate if the character present in both the case.
public class RemoveDuplicateInString {
public static void main(String[] args) {
String s = "ABCDDCA";
RemoveDuplicateInString rs = new RemoveDuplicateInString();
System.out.println(rs.removeDuplicate(s));
}
public String removeDuplicate(String s) {
String retn = null;
boolean[] b = new boolean[256];
char[] ch = s.toCharArray();
for (int i = 0; i < ch.length; i++) {
if (b[ch[i]]) {
ch[i]=' ';
}
else {
b[ch[i]] = true;
}
}
retn = new String(ch);
return retn;
}
}
/* program to remove the duplicate character in string */
/* Author senthilkumar M*/
char *dup_remove(char *str)
{
int i = 0, j = 0, l = strlen(str);
int flag = 0, result = 0;
for(i = 0; i < l; i++) {
result = str[i] - 'a';
if(flag & (1 << result)) {
*/* if duplicate found remove & shift the array*/*
for(j = i; j < l; j++) {
str[j] = str[j+1];
}
i--;
l--; /* duplicates removed so string length reduced by 1 character*/
continue;
}
flag |= (1 << result);
}
return str;
}
public class RemoveCharsFromString {
static String testcase1 = "No, I am going to Noida";
static String testcase2 = "goings";
public static void main(String args[])throws StringIndexOutOfBoundsException{
RemoveCharsFromString testInstance= new RemoveCharsFromString();
String result = testInstance.remove(testcase1,testcase2);
System.out.println(result);
}
//write your code here
public String remove(String str, String str1)throws StringIndexOutOfBoundsException
{ String result=null;
if (str == null)
return "";
try
{
for (int i = 0; i < str1.length (); i++)
{
char ch1=str1.charAt(i);
for(int j=0;j<str.length();j++)
{
char ch = str.charAt (j);
if (ch == ch1)
{
String s4=String.valueOf(ch);
String s5= str.replaceAll(s4, "");
str=s5;
}
}
}
}
catch(Exception e)
{
}
result=str;
return result;
}
}
public static void main(String[] args) {
char[] str = { 'a', 'b', 'a','b','c','e','c' };
for (int i = 1; i < str.length; i++) {
for (int j = 0; j < i; j++) {
if (str[i] == str[j]) {
str[i] = ' ';
}
}
}
System.out.println(str);
}
An improved version for using bitmask to handle 256 chars:
public static void removeDuplicates3(char[] str)
{
long map[] = new long[] {0, 0, 0 ,0};
long one = 1;
for (int i = 0; i < str.length; i++)
{
long chBit = (one << (str[i]%64));
int n = (int) str[i]/64;
if ((map[n] & chBit ) > 0) // duplicate detected
str[i] = 0;
else // add unique char as a bit '1' to the map
map[n] |= chBit ;
}
// get rid of those '\0's
int wi = 1;
for (int i=1; i<str.length; i++)
{
if (str[i]!=0) str[wi++] = str[i];
}
// setting the rest as '\0'
for (;wi<str.length; wi++) str[wi] = 0;
}
Result: "##1!!ASDJasanwAaw.,;..][,[]==--0" ==> "#1!ASDJasnw.,;][=-0" (double quotes not included)
This function removes duplicate from string inline. I have used C# as a coding language and the duplicates are removed inline
public static void removeDuplicate(char[] inpStr)
{
if (inpStr == null) return;
if (inpStr.Length < 2) return;
for (int i = 0; i < inpStr.Length; ++i)
{
int j, k;
for (j = 1; j < inpStr.Length; j++)
{
if (inpStr[i] == inpStr[j] && i != j)
{
for (k = j; k < inpStr.Length - 1; k++)
{
inpStr[k] = inpStr[k + 1];
}
inpStr[k] = ' ';
}
}
}
Console.WriteLine(inpStr);
}
(Java) Avoiding usage of Map, List data structures:
private String getUniqueStr(String someStr) {
StringBuilder uniqueStr = new StringBuilder();
if(someStr != null) {
for(int i=0; i <someStr.length(); i++) {
if(uniqueStr.indexOf(String.valueOf(someStr.charAt(i))) == -1) {
uniqueStr.append(someStr.charAt(i));
}
}
}
return uniqueStr.toString();
}
package com.java.exercise;
public class RemoveCharacter {
/**
* #param args
*/
public static void main(String[] args) {
RemoveCharacter rem = new RemoveCharacter();
char[] ch=rem.GetDuplicates("JavavNNNNNNC".toCharArray());
char[] desiredString="JavavNNNNNNC".toCharArray();
System.out.println(rem.RemoveDuplicates(desiredString, ch));
}
char[] GetDuplicates(char[] input)
{
int ctr=0;
char[] charDupl=new char[20];
for (int i = 0; i <input.length; i++)
{
char tem=input[i];
for (int j= 0; j < i; j++)
{
if (tem == input[j])
{
charDupl[ctr++] = input[j];
}
}
}
return charDupl;
}
public char[] RemoveDuplicates(char[] input1, char []input2)
{
int coutn =0;
char[] out2 = new char[10];
boolean flag = false;
for (int i = 0; i < input1.length; i++)
{
for (int j = 0; j < input2.length; j++)
{
if (input1[i] == input2[j])
{
flag = false;
break;
}
else
{
flag = true;
}
}
if (flag)
{
out2[coutn++]=input1[i];
flag = false;
}
}
return out2;
}
}
Yet another solution, seems to be the most concise so far:
private static String removeDuplicates(String s)
{
String x = new String(s);
for(int i=0;i<x.length()-1;i++)
x = x.substring(0,i+1) + (x.substring(i+1)).replace(String.valueOf(x.charAt(i)), "");
return x;
}
I have written a piece of code to solve the problem.
I have checked with certain values, got the required output.
Note: It's time consuming.
static void removeDuplicate(String s) {
char s1[] = s.toCharArray();
Arrays.sort(s1); //Sorting is performed, a to z
//Since adjacent values are compared
int myLength = s1.length; //Length of the character array is stored here
int i = 0; //i refers to the position of original char array
int j = 0; //j refers to the position of char array after skipping the duplicate values
while(i != myLength-1 ){
if(s1[i]!=s1[i+1]){ //Compares two adjacent characters, if they are not the same
s1[j] = s1[i]; //if not same, then, first adjacent character is stored in s[j]
s1[j+1] = s1[i+1]; //Second adjacent character is stored in s[j+1]
j++; //j is incremented to move to next location
}
i++; //i is incremented
}
//the length of s is i. i>j
String s4 = new String (s1); //Char Array to String
//s4[0] to s4[j+1] contains the length characters after removing the duplicate
//s4[j+2] to s4[i] contains the last set of characters of the original char array
System.out.println(s4.substring(0, j+1));
}
Feel free to run my code with your inputs. Thanks.
public class RemoveRepeatedCharacters {
/**
* This method removes duplicates in a given string in one single pass.
* Keeping two indexes, go through all the elements and as long as subsequent characters match, keep
* moving the indexes in opposite directions. When subsequent characters don't match, copy value at higher index
* to (lower + 1) index.
* Time Complexity = O(n)
* Space = O(1)
*
*/
public static void removeDuplicateChars(String text) {
char[] ch = text.toCharArray();
int i = 0; //first index
for(int j = 1; j < ch.length; j++) {
while(i >= 0 && j < ch.length && ch[i] == ch[j]) {
i--;
j++;
System.out.println("i = " + i + " j = " + j);
}
if(j < ch.length) {
ch[++i] = ch[j];
}
}
//Print the final string
for(int k = 0; k <= i; k++)
System.out.print(ch[k]);
}
public static void main(String[] args) {
String text = "abccbdeefgg";
removeDuplicateChars(text);
}
}
public class StringRedundantChars {
/**
* #param args
*/
public static void main(String[] args) {
//initializing the string to be sorted
String sent = "I love painting and badminton";
//Translating the sentence into an array of characters
char[] chars = sent.toCharArray();
System.out.println("Before Sorting");
showLetters(chars);
//Sorting the characters based on the ASCI character code.
java.util.Arrays.sort(chars);
System.out.println("Post Sorting");
showLetters(chars);
System.out.println("Removing Duplicates");
stripDuplicateLetters(chars);
System.out.println("Post Removing Duplicates");
//Sorting to collect all unique characters
java.util.Arrays.sort(chars);
showLetters(chars);
}
/**
* This function prints all valid characters in a given array, except empty values
*
* #param chars Input set of characters to be displayed
*/
private static void showLetters(char[] chars) {
int i = 0;
//The following loop is to ignore all white spaces
while ('\0' == chars[i]) {
i++;
}
for (; i < chars.length; i++) {
System.out.print(" " + chars[i]);
}
System.out.println();
}
private static char[] stripDuplicateLetters(char[] chars) {
// Basic cursor that is used to traverse through the unique-characters
int cursor = 0;
// Probe which is used to traverse the string for redundant characters
int probe = 1;
for (; cursor < chars.length - 1;) {
// Checking if the cursor and probe indices contain the same
// characters
if (chars[cursor] == chars[probe]) {
System.out.println("Removing char : " + chars[probe]);
// Please feel free to replace the redundant character with
// character. I have used '\0'
chars[probe] = '\0';
// Pushing the probe to the next character
probe++;
} else {
// Since the probe has traversed the chars from cursor it means
// that there were no unique characters till probe.
// Hence set cursor to the probe value
cursor = probe;
// Push the probe to refer to the next character
probe++;
}
}
System.out.println();
return chars;
}
}
This is my solution
public static String removeDup(String inputString){
if (inputString.length()<2) return inputString;
if (inputString==null) return null;
char[] inputBuffer=inputString.toCharArray();
for (int i=0;i<inputBuffer.length;i++){
for (int j=i+1;j<inputBuffer.length;j++){
if (inputBuffer[i]==inputBuffer[j]){
inputBuffer[j]=0;
}
}
}
String result=new String(inputBuffer);
return result;
}
Well I came up with the following solution.
Keeping in mind that S and s are not duplicates. Also I have just one hard coded value.. But the code works absolutely fine.
public static String removeDuplicate(String str)
{
StringBuffer rev = new StringBuffer();
rev.append(str.charAt(0));
for(int i=0; i< str.length(); i++)
{
int flag = 0;
for(int j=0; j < rev.length(); j++)
{
if(str.charAt(i) == rev.charAt(j))
{
flag = 0;
break;
}
else
{
flag = 1;
}
}
if(flag == 1)
{
rev.append(str.charAt(i));
}
}
return rev.toString();
}
I couldn't understand the logic behind the solution so I wrote my simple solution:
public static void removeDuplicates(char[] str) {
if (str == null) return; //If the string is null return
int length = str.length; //Getting the length of the string
if (length < 2) return; //Return if the length is 1 or smaller
for(int i=0; i<length; i++){ //Loop through letters on the array
int j;
for(j=i+1;j<length;j++){ //Loop through letters after the checked letters (i)
if (str[j]==str[i]){ //If you find duplicates set it to 0
str[j]=0;
}
}
}
}
Using guava you can just do something like Sets.newHashSet(charArray).toArray();
If you are not using any libraries, you can still use new HashSet<Char>() and add your char array there.
#include <iostream>
#include <string>
using namespace std;
int main() {
// your code goes here
string str;
cin >> str;
long map = 0;
for(int i =0; i < str.length() ; i++){
if((map & (1L << str[i])) > 0){
str[i] = 0;
}
else{
map |= 1L << str[i];
}
}
cout << str;
return 0;
}

Categories