Boundary Case conditions for String Anagrams - java

I trying to write one string Anagram program but stuck while checking the boundary conditions.
I know there are lots of ways and programs available on internet related to String Anagrams using single loops or using collections framework, but I need the solution for my code that how can I involve boundary cases for the code.
public class StringAnagram {
public static void main(String[] args) {
// TODO Auto-generated method stub
String str = "abc";
String strAnagram = "cba";
boolean areAnagrams = ifAnagrams(str, strAnagram);
System.out.println(areAnagrams);
}
private static boolean ifAnagrams(String str, String strAnagram) {
// TODO Auto-generated method stub
int count = 0;
char[] a = strAnagram.toCharArray();
if (str.length() != strAnagram.length()) {
return false;
}
for (int i = 0; i < str.length(); i++) {
{
System.out.println("str.charAt(i) in outer loop :" + str.charAt(i));
for (int j = 0; j < strAnagram.length(); j++) {
if (str.charAt(i) == strAnagram.charAt(j)) {
System.out.println("str.charAt(i) : " + str.charAt(i));
System.out.println("strAnagram.charAt(j) : " + strAnagram.charAt(j));
count++;
}
}
}
System.out.println(count);
if (count == str.length()) {
return true;
}
}
return false;
}
}
Code is working fine if I am inputting the input likes -
"abc" or "abcd" where each char in string is occuring only one time, but it fails when input is like "aab" can be compared to "abc" and it will show strings are anagrams.
So, how this condition I can handle in my code. Please advice.

The problem with your solution is that it only checks if each character in the first string is present in the second string. There are 2 more conditions you need to consider:
If each character in the second string is also present in the first string
If character count for each character in the first and the second string matches
Your current solution will return True for input of ("aaa", "abc") while it should return False. Implementing the first condition I mentioned above will fix this problem.
After you implement the first condition, your solution will return True for input of ("abb", "aab") while it should return False. Implementing the second condition I mentioned above will fix this problem.
Here is a simple way to make this work:
Map<Character, Integer> charCount = new HashMap<Character, Integer>();
for (int i = 0; i < str.length(); i++) {
char c = str.charAt(i);
if (charCount.containsKey(c)) {
charCount.put(c, charCount.get(c)+1);
} else {
charCount.put(c, 1);
}
}
for (int i = 0; i < strAnagram.length(); i++) {
char c = strAnagram.charAt(i);
if (!charCount.containsKey(c)) return false;
if (charCount.get(c) == 0) return false;
charCount.put(c, charCount.get(c)-1);
}
for (char k : charCount.keySet()) {
if (charCount.get(k) != 0) return false;
}
return true;
Since there are no nested loops, the time complexity is O(n). Even though a Map is used, the space complexity is O(1), since it is guaranteed that the total number of keys will not exceed the number of all possible characters.
This solution is even better than sorting in terms of time and space complexity.

This may still be wildly inefficient. Again I apologize for initially overlooking your requirement that no collection frameworks could be included.
public class StringAnagram {
public static void main(String[] args) {
// TODO Auto-generated method stub
// String str = "abc";
// String strAnagram = "cba";
String str = "abcdd";
String strAnagram = "dccba";
boolean areAnagrams = ifAnagrams(str, strAnagram);
System.out.println(areAnagrams);
}
private static boolean ifAnagrams(String str, String strAnagram) {
int count = 0;
char[] a = strAnagram.toCharArray();
char[] b = str.toCharArray();
String alphaString = "abcdefghijklmnopqrstuvwxyz";
char[] alpha = alphaString.toCharArray();
System.out.println(a);
System.out.println(b);
System.out.println("");
if (str.length() != strAnagram.length()) {
return false;
}
for (int i=0; i < alpha.length; i++) {
int countA = 0;
int countB = 0;
for(int j = 0; j < a.length; j++){
if (a[j] == alpha[i]) {
countA++;
}
if (b[j] == alpha[i]) {
countB++;
}
}
if (countA != countB) {
return false;
}
}
return true;
}
}
This alternate solution makes use of a string that contains all the letters in the alphabet, and iterates through them to check if both strings have the same count of each letter. No frameworks this time :)

Related

Strings and StringBuffer

I have a method that I want to return some path of a string
example if I input : xxdrrryy - it should return rrr, I can only return a string of length 3, so I am trying this , but I'm stalked . it must be the occurrence of a letter three times consecutively
public String countTriple(String str) {
int count = 1;
char currChar = str.charAt(0);
for(int i=1; i<str.length(); i++) {
if(currChar == str.charAt(i)) {
count++;
if(count == 3) {
StringBuilder sb = new StringBuilder("");
for(int j=0; j<3;j++) {
sb.append(currChar);
}
return sb.toString();
}
}
else {
count = 1;
}
currChar = str.charAt(i);
}
return null; //no triple found
}
Unless you have a specific reason not to, I suggest using a regex.
Something like this should suffice
Pattern p = Pattern.compile("(\\w)\\1\\1");
Matcher m = p.matcher("abbccc");
if(m.find()){
System.out.println(m.group());
}
Just import java.util.regex.*
Please update your description it is very difficult to understand what you are trying to say.
But as far as I am understanding you want to find out the count of a particular character in a string.
Say you input "aabbbcccc" then it should return c has 4 characters or something like that.
If that is the case, then simple traverse over each character in that string and add them inside the HashTable and increase the count everytime the character is found, and return the value you require.
I hope this might help you.
This code works. Try this:
public static String countTriple(String str) {
int count = 1;
char currChar = str.charAt(0);
for(int i=1; i<str.length(); i++) {
if(currChar == str.charAt(i)) {
count++;
if(count == 3) {
StringBuilder sb = new StringBuilder("");
for(int j=0; j<3;j++) {
sb.append(currChar);
}
return sb.toString();
}
}
else {
count = 1;
}
currChar = str.charAt(i);
}
return null; //no triple found
}

Check if pattern exists in a String

I would like to check if a pattern exists in a String using iteration.
Here is what I have currently but I keep getting false as a result of it.
public static void main(String args[]) {
String pattern = "abc";
String letters = "abcdef";
char[] patternArray = pattern.toCharArray();
char[] lettersArray = letters.toCharArray();
for(int i = patternArray.length - 1; i<= 2; i++){
for(int j = lettersArray.length - 1; j <= 5;j++){
if(patternArray[i] == lettersArray[j]){
System.out.println("true");
} else{
System.out.println("false");
}
}
}
}
Basically I would like to check if abc exists in the String abcdef
Note: I don't want to use regex because is too easy. I am trying to find a solution without it because I am curious how to do it with iteration.
Here’s a naive string matching program that will find all matches of the pattern.
Not recommended for anything practical, because of the O(mn) time complexity (m and n are the lengths of the search string and pattern respectively).
class Potato
{
public static void main(String args[])
{
char[] search = "flow flow flow over me".toCharArray();
char[] pattern = "flow".toCharArray();
for(int i = 0; i <= search.length - pattern.length; i++)
// `-` don't go till the end of the search str. and overflow
{
boolean flag = true;
for(int j=0; j < pattern.length; j++)
{
if(search[i + j] != pattern[j])
{
flag = false;
break;
}
}
if (flag)
System.out.println("Match found at " + i);
}
}
}
Problem is you have two loops for each array. Here, you need single loop to traverse in both array using same index.
If you want to get all matches, i use a list to save matches addresses in the string.
String pattern = "abc";
String letters = "defabcdefabc";
int i = 0;
List<Integer> matches = new ArrayList();
while (i <= letters.length() - pattern.length()) {
if (letters.substring(i, i + pattern.length()).equals(pattern))
matches.add(i);
i += 1;
}
You can iterate matches if you want to loop all matches with this solution.
Edit:language changed
public static Boolean patternFinder(String str, String pattern){
for (int i = 0; i <= str.length()-pattern.length();i++){
Boolean found = true;
for (int f = 0; f < pattern.length();f++){
if (pattern.charAt(f) != str.charAt(i+f)){
found = false;
break;
}
}
if (found){
return true;
}
}
return false;
}
It's a very simple algorithm
basically, you loop through the string from the beginning and check if all the letters in the pattern are equal to the ones at that specific index.
Why not this:
public static void main(String args[]) {
String pattern = "abc";
String letters = "abcdef";
char[] patternArray = pattern.toCharArray();
char[] lettersArray = letters.toCharArray();
boolean matched = false;
for(int i = 0; i< lettersArray.length-patternArray.length && !matched; i++){
for(int j = 0; j < patternArray.length;j++){
if(patternArray[j] == lettersArray[i+j]&&j+1==patternArray.length){
matched = true;
System.out.println("true");
}
else if(i+1 == lettersArray.length-patternArray.length && j+1 == patternArray.length){
System.out.println("false");
}
}
}

Trouble breaking from a method

I am having difficulties with my method returning true. It is a boolean method that takes two words and tries to see if one can be turned into the other by transposing two neighboring letters. I have had no troubles getting the false boolean. When the code gets to the for loop with an if statement in it it runs fine but does not return true when the if statement is satisfied. For some reason it continues through the for loop. For example, when comparing "teh" and "the" when the loop hits 1 the if statement is satisfied but does not return true, the for lo
public static boolean transposable(String word1, String word2)
{
ArrayList<Character> word1char = new ArrayList<Character>();
ArrayList<Character> word2char = new ArrayList<Character>();
int word1length = word1.length();
int word2length = word2.length();
int count = 0;
String w1 = word1.toUpperCase();
String w2 = word2.toUpperCase();
if(word1length != word2length)
{
return false;
}
for(int i = 0; i < word1length; i++)
{
char letter1 = w1.charAt(i);
word1char.add(letter1);
char letter2 = w2.charAt(i);
word2char.add(letter2);
}
for(int i = 0; i < word1length; i++)
{
char w1c = word1char.get(i);
char w2c = word2char.get(i);
if(w1c == w2c)
{
count++;
}
}
if(count < word1length - 2)
{
return false;
}
for(int i = 0; i < word1length; i++)
{
char w1c = word1char.get(i);
char w2c = word2char.get(i+1);
if(w1c == w2c)
{
return true;
}
}
return false;
}
op just keeps running. What am I doing wrong?
As pointed out in the comments this doesn't seem to be the easiest way around this problem. Here is a solution which tries to follow your logic and includes the use of toUpperCase() and ArrayLists.
Going over your code it looks like you were getting a bit lost in your logic. This is because you had one method trying to do everything. Break things down into smaller methods and you also will benefit by not having to repeat code and it keeps things much cleaner. The code below is tested with Java8 (although there is no reason why this should not work with Java 7).
public static void main(String args[]) {
String word1 = "Hello";
String word2 = "Hlelo";
transposable(word1, word2);
}
private static boolean transposable(String word1, String word2) {
// Get an ArrayList of characters for both words.
ArrayList<Character> word1CharacterList = listOfCharacters(word1);
ArrayList<Character> word2CharacterList = listOfCharacters(word2);
boolean areWordsEqual;
// Check that the size of the CharacterLists is the same
if (word1CharacterList.size() != word2CharacterList.size()) {
return false;
}
// check to see if words are equal to start with
areWordsEqual = checkIfTwoWordsAreTheSame(word1CharacterList, word2CharacterList);
System.out.print("\n" + "Words are equal to be begin with = " + areWordsEqual);
if (!areWordsEqual) {
/*
This loop i must start at 1 because you can't shift an ArrayList index of 0 to the left!
Loops through all the possible combinations and checks if there is a match.
*/
for (int i = 1; i < word1CharacterList.size(); i++) {
ArrayList<Character> adjustedArrayList = shiftNeighbouringCharacter(word2CharacterList, i);
areWordsEqual = checkIfTwoWordsAreTheSame(word1CharacterList, adjustedArrayList);
System.out.print("\n" + "Loop count " + i + " words are equal " + areWordsEqual + word1CharacterList + adjustedArrayList.toString());
if (areWordsEqual) {
break;
}
}
}
return areWordsEqual;
}
// takes in a String as a parameter and returns an ArrayList of Characters in the order of the String parameter.
private static ArrayList<Character> listOfCharacters(String word) {
ArrayList<Character> wordCharacters = new ArrayList<Character>();
String tempWord = word.toUpperCase();
for (int wordLength = 0; wordLength < tempWord.length(); wordLength++) {
Character currentCharacter = tempWord.charAt(wordLength);
wordCharacters.add(currentCharacter);
}
return wordCharacters;
}
// takes in two character arrayLists, and compares each index character.
private static boolean checkIfTwoWordsAreTheSame(ArrayList<Character> characterList1, ArrayList<Character> characterList2) {
// compare list1 against list two
for (int i = 0; i < characterList1.size(); i++) {
Character currentCharacterList1 = characterList1.get(i);
Character currentCharacterList2 = characterList2.get(i);
if (!currentCharacterList1.equals(currentCharacterList2)) {
return false;
}
}
return true;
}
// this method takes in an ArrayList of characters and the initial index that we want to shift one place to the left.
private static ArrayList<Character> shiftNeighbouringCharacter(ArrayList<Character> characterListToShift, int indexToShiftLeft) {
ArrayList<Character> tempCharacterList = new ArrayList<Character>();
int indexAtLeft = indexToShiftLeft - 1;
// fill the new arrayList full of nulls. We will have to remove these nulls later before we can add proper values in their place.
for (int i = 0; i < characterListToShift.size(); i++) {
tempCharacterList.add(null);
}
//get the current index of indexToShift
Character characterOfIndexToShift = characterListToShift.get(indexToShiftLeft);
Character currentCharacterInThePositionToShiftTo = characterListToShift.get(indexAtLeft);
tempCharacterList.remove(indexAtLeft);
tempCharacterList.add(indexAtLeft, characterOfIndexToShift);
tempCharacterList.remove(indexToShiftLeft);
tempCharacterList.add(indexToShiftLeft, currentCharacterInThePositionToShiftTo);
for (int i = 0; i < characterListToShift.size(); i++) {
if (tempCharacterList.get(i) == null) {
Character character = characterListToShift.get(i);
tempCharacterList.remove(i);
tempCharacterList.add(i, character);
}
}
return tempCharacterList;
}
Hope this helps. If you are still struggling then follow along in your debugger. :)

Can anybody help me to correct the following code?

Please help me to identify my mistakes in this code. I am new to Java. Excuse me if I have done any mistake. This is one of codingbat java questions. I am getting Timed Out error message for some inputs like "xxxyakyyyakzzz". For some inputs like "yakpak" and "pakyak" this code is working fine.
Question:
Suppose the string "yak" is unlucky. Given a string, return a version where all the "yak" are removed, but the "a" can be any char. The "yak" strings will not overlap.
public String stringYak(String str) {
String result = "";
int yakIndex = str.indexOf("yak");
if (yakIndex == -1)
return str; //there is no yak
//there is at least one yak
//if there are yaks store their indexes in the arraylist
ArrayList<Integer> yakArray = new ArrayList<Integer>();
int length = str.length();
yakIndex = 0;
while (yakIndex < length - 3) {
yakIndex = str.indexOf("yak", yakIndex);
yakArray.add(yakIndex);
yakIndex += 3;
}//all the yak indexes are stored in the arraylist
//iterate through the arraylist. skip the yaks and get non-yak substrings
for(int i = 0; i < length; i++) {
if (yakArray.contains(i))
i = i + 2;
else
result = result + str.charAt(i);
}
return result;
}
Shouldn't you be looking for any three character sequence starting with a 'y' and ending with a 'k'? Like so?
public static String stringYak(String str) {
char[] chars = (str != null) ? str.toCharArray()
: new char[] {};
StringBuilder sb = new StringBuilder();
for (int i = 0; i < chars.length; i++) {
if (chars[i] == 'y' && chars[i + 2] == 'k') { // if we have 'y' and two away is 'k'
// then it's unlucky...
i += 2;
continue; //skip the statement sb.append
} //do not append any pattern like y1k or yak etc
sb.append(chars[i]);
}
return sb.toString();
}
public static void main(String[] args) {
System.out.println(stringYak("1yik2yak3yuk4")); // Remove the "unlucky" strings
// The result will be 1234.
}
It looks like your programming assignment. You need to use regular expressions.
Look at http://www.vogella.com/articles/JavaRegularExpressions/article.html#regex for more information.
Remember, that you can not use contains. Your code maybe something like
result = str.removeall("y\wk")
you can try this
public static String stringYak(String str) {
for (int i = 0; i < str.length(); i++) {
if(str.charAt(i)=='y'){
str=str.replace("yak", "");
}
}
return str;
}

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