How to add new values into existing upperCase to new lowerCase - java

I am developing a method which takes ArrayList as an argument.
Then, the method makes some changes into the array and returns transformed arrayList.
The input array is going to be like that {A123, C123, 15B2} and I would like to get the following output {Aa123, Cc123, 15Bb2}.
That is to say, after any capital letter I need to add the same lowercase letter.
And there are any order and quantity of letters, e.g. it is also possible to get strings like those Hkjk124, hy71.
The method is shown below:
protected ArrayList<String> enrichValues(ArrayList<String> list) {
for (int i = 0; i < list.size(); i++) {
char[] charArray = list.get(i).toCharArray();
List<Character> listChars = new ArrayList<>();
for (char c : charArray) {
listChars.add(c);
}
for (int j = 0; j < listChars.size(); j++) {
if (listChars.get(j).charValue() == 'A') {
listChars.add(j + 1, 'a');
}
}
String newChar = "";
for (Character c : listChars)
newChar += c.toString();
list.set(i, newChar);
}
return list;
}
The main problem I have faced to is that I do not know how to check if a letter is uppercase.
I failed to apply something like:
if(Character.isLetter(c) && Character.isUpperCase(c)) {
listChars.add(j + 1, 'a');
}
Because of that I have to add lots of checks:
if (listChars.get(j).charValue() == 'B') {
listChars.add(j + 1, 'b');
}
if (listChars.get(j).charValue() == 'C') {
listChars.add(j + 1, 'c');
}
But it is a very bad approach. I would appreciate any help.

Here's a way of doing it that works like a charm :
public static ArrayList<String> enrichValues(ArrayList<String> values){
ArrayList<String> array = new ArrayList<String>();
for (String str : values){ //For each string
StringBuilder copy = new StringBuilder();
for (char c : str.toCharArray()) {//For each char
copy.append(c);
if(Character.isLetter(c) && Character.isUpperCase(c)){
copy.append(Character.toLowerCase(c));
}
}
array.add(copy.toString());
}
return array;
}
Example :
public static void main(String[] args) {
String a = "A123";
String b = "C123";
String c = "15B2";
String d = " Hkjk124";
String e = "hy71";
String g = "AbCdE645 DeeeFFD";
ArrayList<String> values = new ArrayList<String>();
values.add(a);
values.add(b);
values.add(c);
values.add(d);
values.add(e);
values.add(g);
values = enrichValues(values);
System.out.println(values.toString());
}
Output : [Aa123, Cc123, 15Bb2, Hhkjk124, hy71, AabCcdEe645 DdeeeFfFfDd]

When you are writing some method which accepts concrete implementation of the List interface such as ArrayList, consider to change it to List type. This will allow you to pass in any form of list: LinkedList, ArrayList, ...
Another thing you shoud know is, that joining strings via += is inefficient, as it creates new String instance each time += is applied. Instead of doing this, you should use StringBuilder which allocates resizable buffer for string where you can append other characters.
Condition Character.isLetter(c) && Character.isUpperCase(c) is redudant, since Character.isUpperCase(char) already returns false for non-letter characters.
If you need to convert character to lower-case use Character.toLowerCase(char).
Note, characters are basically integers, so when you write something like this: char c = 65; and print the value, you will see 'A' in output, because 65 is ASCII value for character 'A'. If you add 32, you will obtain 97 which is 'a'. Putting all together you can write something like this:
char c = ...;
// c is in range of upper-case characters
if (c >= 65 && c <= 90) {
char lower = c + 32;
}
// c is in range of lower-case characters
if (c >= 97 && c <= 122) {
char upper = c - 32;
}
Try following method which mutates original list:
protected List<String> enrichValues(List<String> list) {
for (int i = 0; i < list.size(); i++) {
StringBuilder sb = new StringBuilder(list.get(i));
for (int j = 0; j < sb.length(); j++) {
char c = sb.charAt(j);
if ( Character.isUpperCase(c) ) {
sb.insert(++j, Character.toLowerCase(c));
}
}
list.set(i, sb.toString());
}
return list;
}
or this one which creates new list for transformed values:
protected List<String> enrichValues(List<String> original) {
List<String> transformed = new ArrayList<>(list.size());
for (String s : original) {
StringBuilder sb = new StringBuilder(s);
for (int j = 0; j < sb.length(); j++) {
char c = sb.charAt(j);
if ( Character.isUpperCase(c) ) {
sb.insert(++j, Character.toLowerCase(c));
}
}
transformed.add(sb.toString());
}
return transformed;
}
Test:
System.out.println( enrichValues(Arrays.asList("A123", "C123", "15B2")) );
// Output: [Aa123, Cc123, 15Bb2]

To find out whether if a letter is upper case you just need to use the ASCII alphabet. Upper case characters go from 65 to 90.
So you just need to use a loop over the length of your string and check for each char if it´s ASCII value is between 65 and 90. So it would look like this, assuming the variable temp is one character of the string:
if((int)temp >= 65 && (int)temp <= 90){
//Add the lower case character by adding 22 to the character value (lower case are from 97-122)
char additionalChar = ((int)temp)+22;
}
Note that I´ve not tried the code so ((int)temp)+22 might not work that way, but it would look pretty similar.

There is an easier way to do this with regular expressions:
final ArrayList< String > outputList = new ArrayList<>();
for ( String str : list ) {
final String[] letters = str.replaceAll( "[^A-Z]", "" ).toLowerCase().split( "" );
final String result = String.format( str.replaceAll( "([A-Z])", "$1%s" ), letters );
outputList.add( result );
}
return outputList;

Related

Decipher the sequence using Java 8

Steps for Deciphering the message
remove 3 at end of the string
replace ASCII values at even places(number clusters) with corresponding characters value.
replace * with spacing " ".
reverse the string
swap case of string- lowercase to upper case and vice versa.
Sample input: ?85O89*69R65*87O104*33I1043
Require output: Hi! How are you?
This is the whole method that I have written.
public String deciphering(String ciphered) {
StringBuilder a = new StringBuilder(ciphered);
StringBuilder b = a.deleteCharAt(a.length()-1);
char[] ch = new char[b.length()];
StringBuilder c = new StringBuilder();
for (int i = 0; i < b.length(); i++) {
ch[i] = b.charAt(i);
}
for (int i = 0; i < ch.length; i++) {
if(!Character.isDigit(ch[i]))
{
c.append(ch[i]);
}else
{
String temp = new String();
while(Character.isDigit(ch[i]) &&(i<b.length())){
temp = temp + ch[i];
i++;
}
int number = Integer.parseInt(temp);
char p = (char)number;
c.append(p);
}
}
String d = c.toString();
String e = d.replace('*', ' ');
StringBuffer f = new StringBuffer(e);
StringBuffer g = f.reverse();
for (int i = 0; i < g.length(); i++) {
if (Character.isLowerCase(g.charAt(i))){
char x = Character.toUpperCase(g.charAt(i));
g.setCharAt(i, x);
} else if (Character.isUpperCase(g.charAt(i))) {
char x = Character.toLowerCase(g.charAt(i));
g.setCharAt(i, x);
}
}
return g.toString();
}
You are incrementing i twice past the last digit of a chunk - when you exit your inner loop i is indexing the first non-digit character, then when you reach the end of the for loop body, the for loop is incrementing i again.
It may be better to split the input string into parts with non-digit delimiters and keep the delimiters using the following regular expression (using look-ahead and look-behind as described here) after removing the last character:
str.substring(0, str.length() - 1).split("(?<=\\D)|(?=\\D)")
Then Stream API may be used to convert each string into a separate character and insert these characters into prepared StringBuilder to implement reverse order in the result:
public static String decipher(String str) {
StringBuilder sb = new StringBuilder(str.length());
Arrays.stream(
str.substring(0, str.length() - 1).split("(?<=\\D)|(?=\\D)")
)
.map(p -> p.matches("\\d+") ? (char) Integer.parseInt(p): p.charAt(0))
.map(c -> c == '*' ? ' '
: Character.isLowerCase(c) ? Character.toUpperCase(c)
: Character.isUpperCase(c) ? Character.toLowerCase(c)
: c
)
.forEach(c -> sb.insert(0, c));
return sb.toString();
}
Test:
System.out.println(decipher("?85O89*69R65*87O104*33I1043"));
Output:
Hi! How are you?

Replace characters in string with a custom alphabet

I have written this code that replaces the characters in a string with a custom supplied alphabet:
//Replaces characters in string with custom alphabet.
public static String getStringWithCustomAlphabet(String string, String customAlphabet){
String shiftedString = "";
//Loop through every character in #plainText
for (int i = 0; i < string.length(); i++) {
//Store current character of loop in #charToAdd
char charToAdd = string.charAt(i);
int index = getAlphabet().indexOf(charToAdd);
//If index is valid
if (index != -1) charToAdd = customAlphabet.charAt(index);
//Add the character to #cipherText
shiftedString += charToAdd;
}
return shiftedString;
}
public static String getAlphabet() {
return "abcdefghijklmnopqrstuvwxyz ";
}
This code works. However, I want to be able to use not only a String alphabet but an integer alphabet. So, for example:
int[] numberArray {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26};
getStringWithCustomAlphabet("abcxyz", numberArray); //Should return 0,1,2,23,24,25
Maybe there is some way to simply this code and not use a for loop?
Strategy pattern may save you a lot of time and give you maximum flexibility. Suppose that we define an AlphabetConverter interface, as:
#FunctionalInterface
interface AlphabetConverter {
String convert(char ch);
}
Then, define the convertAlphabet method accepting an AlphabetConverter, as:
public String convertAlphabet(String actual, AlphabetConverter converter) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < actual.length(); i++) {
sb.append(converter.convert(actual.charAt(i)));
}
return sb.ToString();
}
Now, you can implement AlphabetConverter, one for replacement with String alphabet, and one for int array, or even use a lambda function.
For lower case use this :
String str = "abcdef";
char[] ch = str.toCharArray();
for (char c : ch) {
int temp = (int) c;
int temp_integer = 96; //for lower case
if (temp <= 122 & temp >= 97)
System.out.print(temp-temp_integer);
}
Output will be -:123456
For Upper case :
String str = "DEFGHI";
char[] ch = str.toCharArray();
for (char c : ch) {
int temp = (int) c;
int temp_integer = 64; //for upper case
if (temp <= 90 & temp >= 65)
System.out.print(temp-temp_integer);
}
Output Will be -:456789

Java: How to remove all occurrences of a set of letters stored as a string from another string?

I am trying to figure out how to write a method that will remove letters in a
string based on another string. The method would end up like so:
removeLetter("file", "fe")
The only thing that should be returned is the string "il". So far I have something like this:
public class h
{
public static void main(String[] args)
{
String a="file";
String b="fe";
char letter;
int i;
int j;
for (letter = 'a'; letter <= 'z'; letter++)
{
for (i=0; i < a.length()-1; i++)
{
for (j=0; j < b.length()-1; j++) // This is the loop i get stuck on
{
char r = b.charAt(j);
char s = a.charAt(i);
if ( letter == r && letter == s);
System.out.print(r + " " + s);
}
}
}
}
}
I know the bottom part is wrong but I am not sure where to go from here.
You can do this with a regular expression:
a.replaceAll("[" + b + "]", "")
This works by constructing a character class like [fe], and replacing characters which match that with the empty string.
Of course, this is a bit of a hack, in that you can easily choose b such that it won't yield a valid regular expression. However, if you know that b will only ever contain letters, this would work.
Here's a pretty simple nested array using a flag boolean :
public static void main(String[] args) {
String a = "file";
String b = "f";
String c = "";
StringBuilder sb = new StringBuilder();
boolean contains;
for (int i = 0 ; i < a.length() ; i++){
contains = false;
for (int j = 0 ; j < b.length() ; j++){
if (a.charAt(i) == b.charAt(j)) contains = true;
}
if (!contains) sb.append(a.charAt(i));
}
System.out.println(sb);
}
It checks every char of the first word with the chars of the second and changes the flag to true if the char is contained in both.
If it is not the case, the char of the first word is added to the new String, if the contrary, nothing happens and we continue to the next char of the first String.
Let's remove all the vowels of this word : Supercalifragilisticexpialidocious
String a = "Supercalifragilisticexpialidocious";
String b = "aeiou";
Here's the output :
Sprclfrglstcxpldcs

Java: Remove non alphabet character from a String without regex

Is there a way to remove all non alphabet character from a String without regex?
I'm trying to check if the String is a palindrome
This is what i tried so far.
public static boolean isPalindrome( String text )
{
int textLength = text.length() - 1;
String reformattedText = text.trim().toLowerCase();
for( int i = 0; i <= textLength; i++ )
{
if( reformattedText.charAt( i ) != reformattedText.charAt( textLength - i ) )
{
return false;
}
}
return true;
}
But if the input is:
System.out.println( isPalindrome( "Are we not pure? No sir! Panama’s moody"
+ "Noriega brags. It is garbage! Irony dooms a man; a prisoner up to new era." ) );
It should be true.
I'm really having a hard time thinking of how to remove or ignore those non alphabet characters on the String.
I would do something like this:
public static String justAlphaChars(String text) {
StringBuilder builder = new StringBuilder();
for (char ch : text.toCharArray())
if (Character.isAlphabetic(ch))
builder.append(ch);
return builder.toString();
}
Just tested method above in your example bellow and worked. Returned true.
System.out.println( isPalindrome( justAlphaChars ( "Are we not pure? No sir! Panama’s moody"
+ "Noriega brags. It is garbage! Irony dooms a man; a prisoner up to new era." ) ) );
OOPS. Java, not Python.
You can still use list-like access in Java, just a bit more work.
char[] letters = text.toCharArray();
int nletters = 0;
for (int i=0; i<letters.length; ++i) {
if (Character.isLetter(letters[i])
letters[nletters++] = Character.toUpperCase(letters[i]);
}
// print out letters in array:
System.out.print("letters only: ");
for (int i=0; i<nletters; ++i) {
System.out.print(letters[i]);
}
System.out.println();
Now use the first nletters positions only in the letters array, since those positions will hold the lowercased letters from the input. An example that just displays the remaining characters is included above.
Now write a loop to compare letters[0] with letters[nletters-1], letters[1] with letters[nletters-2], and so on. If all pairs are equal, you have a palindrome.
String removeNonAlpha(final String word) {
final StringBuilder result = new StringBuilder();
for (final char ch : word.toCharArray()) {
final int ascii = ch;
if (((ascii >= 65) && (ascii <= 90)) || ((ascii >= 97) && (ascii <= 122))) {
result.append(ch);
}
}
return result.toString();
}
Explanation:
The method will retrieve a string containing only A-Z and a-z characters.
I am simply verifying the ascii code for the given char.
Please refer to the ASCII code table

Removing duplicates from a String in Java

I am trying to iterate through a string in order to remove the duplicates characters.
For example the String aabbccdef should become abcdef
and the String abcdabcd should become abcd
Here is what I have so far:
public class test {
public static void main(String[] args) {
String input = new String("abbc");
String output = new String();
for (int i = 0; i < input.length(); i++) {
for (int j = 0; j < output.length(); j++) {
if (input.charAt(i) != output.charAt(j)) {
output = output + input.charAt(i);
}
}
}
System.out.println(output);
}
}
What is the best way to do this?
Convert the string to an array of char, and store it in a LinkedHashSet. That will preserve your ordering, and remove duplicates. Something like:
String string = "aabbccdefatafaz";
char[] chars = string.toCharArray();
Set<Character> charSet = new LinkedHashSet<Character>();
for (char c : chars) {
charSet.add(c);
}
StringBuilder sb = new StringBuilder();
for (Character character : charSet) {
sb.append(character);
}
System.out.println(sb.toString());
Using Stream makes it easy.
noDuplicates = Arrays.asList(myString.split(""))
.stream()
.distinct()
.collect(Collectors.joining());
Here is some more documentation about Stream and all you can do with
it :
https://docs.oracle.com/javase/8/docs/api/java/util/stream/package-summary.html
The 'description' part is very instructive about the benefits of Streams.
Try this simple solution:
public String removeDuplicates(String input){
String result = "";
for (int i = 0; i < input.length(); i++) {
if(!result.contains(String.valueOf(input.charAt(i)))) {
result += String.valueOf(input.charAt(i));
}
}
return result;
}
I would use the help of LinkedHashSet. Removes dups (as we are using a Set, maintains the order as we are using linked list impl). This is kind of a dirty solution. there might be even a better way.
String s="aabbccdef";
Set<Character> set=new LinkedHashSet<Character>();
for(char c:s.toCharArray())
{
set.add(Character.valueOf(c));
}
Create a StringWriter. Run through the original string using charAt(i) in a for loop. Maintain a variable of char type keeping the last charAt value. If you iterate and the charAt value equals what is stored in that variable, don't add to the StringWriter. Finally, use the StringWriter.toString() method and get a string, and do what you need with it.
Here is an improvement to the answer by Dave.
It uses HashSet instead of the slightly more costly LinkedHashSet, and reuses the chars buffer for the result, eliminating the need for a StringBuilder.
String string = "aabbccdefatafaz";
char[] chars = string.toCharArray();
Set<Character> present = new HashSet<>();
int len = 0;
for (char c : chars)
if (present.add(c))
chars[len++] = c;
System.out.println(new String(chars, 0, len)); // abcdeftz
Java 8 has a new String.chars() method which returns a stream of characters in the String. You can use stream operations to filter out the duplicate characters like so:
String out = in.chars()
.mapToObj(c -> Character.valueOf((char) c)) // bit messy as chars() returns an IntStream, not a CharStream (which doesn't exist)
.distinct()
.map(Object::toString)
.collect(Collectors.joining(""));
String input = "AAAB";
String output = "";
for (int index = 0; index < input.length(); index++) {
if (input.charAt(index % input.length()) != input
.charAt((index + 1) % input.length())) {
output += input.charAt(index);
}
}
System.out.println(output);
but you cant use it if the input has the same elements, or if its empty!
Code to remove the duplicate characters in a string without using any additional buffer. NOTE: One or two additional variables are fine. An extra array is not:
import java.util.*;
public class Main{
public static char[] removeDupes(char[] arr){
if (arr == null || arr.length < 2)
return arr;
int len = arr.length;
int tail = 1;
for(int x = 1; x < len; x++){
int y;
for(y = 0; y < tail; y++){
if (arr[x] == arr[y]) break;
}
if (y == tail){
arr[tail] = arr[x];
tail++;
}
}
return Arrays.copyOfRange(arr, 0, tail);
}
public static char[] bigArr(int len){
char[] arr = new char[len];
Random r = new Random();
String alphabet = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890!##$%^&*()-=_+[]{}|;:',.<>/?`~";
for(int x = 0; x < len; x++){
arr[x] = alphabet.charAt(r.nextInt(alphabet.length()));
}
return arr;
}
public static void main(String args[]){
String result = new String(removeDupes(new char[]{'a', 'b', 'c', 'd', 'a'}));
assert "abcd".equals(result) : "abcda should return abcd but it returns: " + result;
result = new String(removeDupes(new char[]{'a', 'a', 'a', 'a'}));
assert "a".equals(result) : "aaaa should return a but it returns: " + result;
result = new String(removeDupes(new char[]{'a', 'b', 'c', 'a'}));
assert "abc".equals(result) : "abca should return abc but it returns: " + result;
result = new String(removeDupes(new char[]{'a', 'a', 'b', 'b'}));
assert "ab".equals(result) : "aabb should return ab but it returns: " + result;
result = new String(removeDupes(new char[]{'a'}));
assert "a".equals(result) : "a should return a but it returns: " + result;
result = new String(removeDupes(new char[]{'a', 'b', 'b', 'a'}));
assert "ab".equals(result) : "abba should return ab but it returns: " + result;
char[] arr = bigArr(5000000);
long startTime = System.nanoTime();
System.out.println("2: " + new String(removeDupes(arr)));
long endTime = System.nanoTime();
long duration = (endTime - startTime);
System.out.println("Program took: " + duration + " nanoseconds");
System.out.println("Program took: " + duration/1000000000 + " seconds");
}
}
How to read and talk about the above code:
The method called removeDupes takes an array of primitive char called arr.
arr is returned as an array of primitive characters "by value". The arr passed in is garbage collected at the end of Main's member method removeDupes.
The runtime complexity of this algorithm is O(n) or more specifically O(n+(small constant)) the constant being the unique characters in the entire array of primitive chars.
The copyOfRange does not increase runtime complexity significantly since it only copies a small constant number of items. The char array called arr is not stepped all the way through.
If you pass null into removeDupes, the method returns null.
If you pass an empty array of primitive chars or an array containing one value, that unmodified array is returned.
Method removeDupes goes about as fast as physically possible, fully utilizing the L1 and L2 cache, so Branch redirects are kept to a minimum.
A 2015 standard issue unburdened computer should be able to complete this method with an primitive char array containing 500 million characters between 15 and 25 seconds.
Explain how this code works:
The first part of the array passed in is used as the repository for the unique characters that are ultimately returned. At the beginning of the function the answer is: "the characters between 0 and 1" as between 0 and tail.
We define the variable y outside of the loop because we want to find the first location where the array index that we are looking at has been duplicated in our repository. When a duplicate is found, it breaks out and quits, the y==tail returns false and the repository is not contributed to.
when the index x that we are peeking at is not represented in our repository, then we pull that one and add it to the end of our repository at index tail and increment tail.
At the end, we return the array between the points 0 and tail, which should be smaller or equal to in length to the original array.
Talking points exercise for coder interviews:
Will the program behave differently if you change the y++ to ++y? Why or why not.
Does the array copy at the end represent another 'N' pass through the entire array making runtime complexity O(n*n) instead of O(n) ? Why or why not.
Can you replace the double equals comparing primitive characters with a .equals? Why or why not?
Can this method be changed in order to do the replacements "by reference" instead of as it is now, "by value"? Why or why not?
Can you increase the efficiency of this algorithm by sorting the repository of unique values at the beginning of 'arr'? Under which circumstances would it be more efficient?
public class RemoveRepeated4rmString {
public static void main(String[] args) {
String s = "harikrishna";
String s2 = "";
for (int i = 0; i < s.length(); i++) {
Boolean found = false;
for (int j = 0; j < s2.length(); j++) {
if (s.charAt(i) == s2.charAt(j)) {
found = true;
break; //don't need to iterate further
}
}
if (found == false) {
s2 = s2.concat(String.valueOf(s.charAt(i)));
}
}
System.out.println(s2);
}
}
public static void main(String a[]){
String name="Madan";
System.out.println(name);
StringBuilder sb=new StringBuilder(name);
for(int i=0;i<name.length();i++){
for(int j=i+1;j<name.length();j++){
if(name.charAt(i)==name.charAt(j)){
sb.deleteCharAt(j);
}
}
}
System.out.println("After deletion :"+sb+"");
}
import java.util.Scanner;
public class dublicate {
public static void main(String... a) {
System.out.print("Enter the String");
Scanner Sc = new Scanner(System.in);
String st=Sc.nextLine();
StringBuilder sb=new StringBuilder();
boolean [] bc=new boolean[256];
for(int i=0;i<st.length();i++)
{
int index=st.charAt(i);
if(bc[index]==false)
{
sb.append(st.charAt(i));
bc[index]=true;
}
}
System.out.print(sb.toString());
}
}
To me it looks like everyone is trying way too hard to accomplish this task. All we are concerned about is that it copies 1 copy of each letter if it repeats. Then because we are only concerned if those characters repeat one after the other the nested loops become arbitrary as you can just simply compare position n to position n + 1. Then because this only copies things down when they're different, to solve for the last character you can either append white space to the end of the original string, or just get it to copy the last character of the string to your result.
String removeDuplicate(String s){
String result = "";
for (int i = 0; i < s.length(); i++){
if (i + 1 < s.length() && s.charAt(i) != s.charAt(i+1)){
result = result + s.charAt(i);
}
if (i + 1 == s.length()){
result = result + s.charAt(i);
}
}
return result;
}
String str1[] ="Hi helloo helloo oooo this".split(" ");
Set<String> charSet = new LinkedHashSet<String>();
for (String c: str1)
{
charSet.add(c);
}
StringBuilder sb = new StringBuilder();
for (String character : charSet)
{
sb.append(character);
}
System.out.println(sb.toString());
I think working this way would be more easy,,,
Just pass a string to this function and the job is done :) .
private static void removeduplicate(String name)
{ char[] arr = name.toCharArray();
StringBuffer modified =new StringBuffer();
for(char a:arr)
{
if(!modified.contains(Character.toString(a)))
{
modified=modified.append(Character.toString(a)) ;
}
}
System.out.println(modified);
}
public class RemoveDuplicatesFromStingsMethod1UsingLoops {
public static void main(String[] args) {
String input = new String("aaabbbcccddd");
String output = "";
for (int i = 0; i < input.length(); i++) {
if (!output.contains(String.valueOf(input.charAt(i)))) {
output += String.valueOf(input.charAt(i));
}
}
System.out.println(output);
}
}
output: abcd
You can't. You can create a new String that has duplicates removed. Why aren't you using StringBuilder (or StringBuffer, presumably)?
You can run through the string and store the unique characters in a char[] array, keeping track of how many unique characters you've seen. Then you can create a new String using the String(char[], int, int) constructor.
Also, the problem is a little ambiguous—does “duplicates” mean adjacent repetitions? (In other words, what should happen with abcab?)
Oldschool way (as we wrote such a tasks in Apple ][ Basic, adapted to Java):
int i,j;
StringBuffer str=new StringBuffer();
Scanner in = new Scanner(System.in);
System.out.print("Enter string: ");
str.append(in.nextLine());
for (i=0;i<str.length()-1;i++){
for (j=i+1;j<str.length();j++){
if (str.charAt(i)==str.charAt(j))
str.deleteCharAt(j);
}
}
System.out.println("Removed non-unique symbols: " + str);
Here is another logic I'd like to share. You start comparing from midway of the string length and go backward.
Test with:
input = "azxxzy";
output = "ay";
String removeMidway(String input){
cnt = cnt+1;
StringBuilder str = new StringBuilder(input);
int midlen = str.length()/2;
for(int i=midlen-1;i>0;i--){
for(int j=midlen;j<str.length()-1;j++){
if(str.charAt(i)==str.charAt(j)){
str.delete(i, j+1);
midlen = str.length()/2;
System.out.println("i="+i+",j="+j+ ",len="+ str.length() + ",midlen=" + midlen+ ", after deleted = " + str);
}
}
}
return str.toString();
}
Another possible solution, in case a string is an ASCII string, is to maintain an array of 256 boolean elements to denote ASCII character appearance in a string. If a character appeared for the first time, we keep it and append to the result. Otherwise just skip it.
public String removeDuplicates(String input) {
boolean[] chars = new boolean[256];
StringBuilder resultStringBuilder = new StringBuilder();
for (Character c : input.toCharArray()) {
if (!chars[c]) {
resultStringBuilder.append(c);
chars[c] = true;
}
}
return resultStringBuilder.toString();
}
This approach will also work with Unicode string. You just need to increase chars size.
Solution using JDK7:
public static String removeDuplicateChars(final String str){
if (str == null || str.isEmpty()){
return str;
}
final char[] chArray = str.toCharArray();
final Set<Character> set = new LinkedHashSet<>();
for (char c : chArray) {
set.add(c);
}
final StringBuilder sb = new StringBuilder();
for (Character character : set) {
sb.append(character);
}
return sb.toString();
}
String str = "eamparuthik#gmail.com";
char[] c = str.toCharArray();
String op = "";
for(int i=0; i<=c.length-1; i++){
if(!op.contains(c[i] + ""))
op = op + c[i];
}
System.out.println(op);
public static String removeDuplicateChar(String str){
char charArray[] = str.toCharArray();
StringBuilder stringBuilder= new StringBuilder();
for(int i=0;i<charArray.length;i++){
int index = stringBuilder.toString().indexOf(charArray[i]);
if(index <= -1){
stringBuilder.append(charArray[i]);
}
}
return stringBuilder.toString();
}
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class RemoveDuplicacy
{
public static void main(String args[])throws IOException
{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
System.out.print("Enter any word : ");
String s = br.readLine();
int l = s.length();
char ch;
String ans=" ";
for(int i=0; i<l; i++)
{
ch = s.charAt(i);
if(ch!=' ')
ans = ans + ch;
s = s.replace(ch,' '); //Replacing all occurrence of the current character by a space
}
System.out.println("Word after removing duplicate characters : " + ans);
}
}
public static void main(String[] args) {
int i,j;
StringBuffer str=new StringBuffer();
Scanner in = new Scanner(System.in);
System.out.print("Enter string: ");
str.append(in.nextLine());
for (i=0;i<str.length()-1;i++)
{
for (j=1;j<str.length();j++)
{
if (str.charAt(i)==str.charAt(j))
str.deleteCharAt(j);
}
}
System.out.println("Removed String: " + str);
}
This is improvement on solution suggested by #Dave. Here, I am implementing in single loop only.
Let's reuse the return of set.add(T item) method and add it simultaneously in StringBuffer if add is successfull
This is just O(n). No need to make a loop again.
String string = "aabbccdefatafaz";
char[] chars = string.toCharArray();
StringBuilder sb = new StringBuilder();
Set<Character> charSet = new LinkedHashSet<Character>();
for (char c : chars) {
if(charSet.add(c) ){
sb.append(c);
}
}
System.out.println(sb.toString()); // abcdeftz
Simple solution is to iterate through the given string and put each unique character into another string(in this case, a variable result ) if this string doesn't contain that particular character.Finally return result string as output.
Below is working and tested code snippet for removing duplicate characters from the given string which has O(n) time complexity .
private static String removeDuplicate(String s) {
String result="";
for (int i=0 ;i<s.length();i++) {
char ch = s.charAt(i);
if (!result.contains(""+ch)) {
result+=""+ch;
}
}
return result;
}
If the input is madam then output will be mad.
If the input is anagram then output will be angrm
Hope this helps.
Thanks
For the simplicity of the code- I have taken hardcore input, one can take input by using Scanner class also
public class KillDuplicateCharInString {
public static void main(String args[]) {
String str= "aaaabccdde ";
char arr[]= str.toCharArray();
int n = arr.length;
String finalStr="";
for(int i=0;i<n;i++) {
if(i==n-1){
finalStr+=arr[i];
break;
}
if(arr[i]==arr[i+1]) {
continue;
}
else {
finalStr+=arr[i];
}
}
System.out.println(finalStr);
}
}
public static void main (String[] args)
{
Scanner sc = new Scanner(System.in);
String s = sc.next();
String str = "";
char c;
for(int i = 0; i < s.length(); i++)
{
c = s.charAt(i);
str = str + c;
s = s.replace(c, ' ');
if(i == s.length() - 1)
{
System.out.println(str.replaceAll("\\s", ""));
}
}
}
package com.st.removeduplicate;
public class RemoveDuplicate {
public static void main(String[] args) {
String str1="shushil",str2="";
for(int i=0; i<=str1.length()-1;i++) {
int count=0;
for(int j=0;j<=i;j++) {
if(str1.charAt(i)==str1.charAt(j))
count++;
if(count >1)
break;
}
if(count==1)
str2=str2+str1.charAt(i);
}
System.out.println(str2);
}
}

Categories