Sorting characters alphabetically in a String - java

Could smb please explaing the process of sorting characters of String alphabetically? For example, if I have String "hello" the output should be "ehllo" but my code is doing it wrong.
public static void main(String[] args)
{
String result = "";
Scanner kbd = new Scanner(System.in);
String input = kbd.nextLine();
for(int i = 1; i < input.length(); i++)
{
if(input.charAt(i-1) < input.charAt(i))
result += input.charAt(i-1);
//else
// result += input.charAt(i);
}
System.out.println(result);
}
}

You may do the following thing -
1. Convert your String to char[] array.
2. Using Arrays.sort() sort your char array
Code snippet:
String input = "hello";
char[] charArray = input.toCharArray();
Arrays.sort(charArray);
String sortedString = new String(charArray);
System.out.println(sortedString);
Or if you want to sort the array using for loop (for learning purpose) you may use (But I think the first one is best option ) the following code snippet-
input="hello";
char[] charArray = input.toCharArray();
length = charArray.length();
for(int i=0;i<length;i++){
for(int j=i+1;j<length;j++){
if (charArray[j] < charArray[i]) {
char temp = charArray[i];
charArray[i]=arr[j];
charArray[j]=temp;
}
}
}

You can sort a String in Java 8 using Stream as below:
String sortedString =
Stream.of("hello".split(""))
.sorted()
.collect(Collectors.joining());

Procedure :
At first convert the string to char array
Then sort the array of character
Convert the character array to string
Print the string
Code snippet:
String input = "world";
char[] arr = input.toCharArray();
Arrays.sort(arr);
String sorted = new String(arr);
System.out.println(sorted);

Sorting as a task has a lower bound of O(n*logn), with n being the number of elements to sort. What this means is that if you are using a single loop with simple operations, it will not be guaranteed to sort correctly.
A key element in sorting is deciding what you are sorting by. In this case its alphabetically, which, if you convert each character to a char, equates to sorting in ascending order, since a char is actually just a number that the machine maps to the character, with 'a' < 'b'. The only gotcha to look out for is mixed case, since 'z' < 'A'. To get around, this, you can use str.tolower(). I'd recommend you look up some basic sorting algorithms too.

Your for loop is starting at 1 and it should be starting at zero:
for(int i = 0; i < input.length(); i++){...}

You can do this using Arrays.sort, if you put the characters into an array first.
Character[] chars = new Character[str.length()];
for (int i = 0; i < chars.length; i++)
chars[i] = str.charAt(i);
// sort the array
Arrays.sort(chars, new Comparator<Character>() {
public int compare(Character c1, Character c2) {
int cmp = Character.compare(
Character.toLowerCase(c1.charValue()),
Character.toLowerCase(c2.charValue())
);
if (cmp != 0) return cmp;
return Character.compare(c1.charValue(), c2.charValue());
}
});
Now build a string from it using StringBuilder.

Most basic and brute force approach using the two for loop:
It sort the string but with the cost of O(n^2) time complexity.
public void stringSort(String str){
char[] token = str.toCharArray();
for(int i = 0; i<token.length; i++){
for(int j = i+1; j<token.length; j++){
if(token[i] > token[j]){
char temp = token[i];
token[i] = token[j];
token[j] = temp;
}
}
}
System.out.print(Arrays.toString(token));
}

public class SortCharcterInString {
public static void main(String[] args) {
String str = "Hello World";
char[] arr;
List<Character> L = new ArrayList<Character>();
for (int i = 0; i < str.length(); i++) {
arr = str.toLowerCase().toCharArray();
L.add(arr[i]);
}
Collections.sort(L);
str = L.toString();
str = str.replaceAll("\\[", "").replaceAll("\\]", "")
.replaceAll("[,]", "").replaceAll(" ", "");
System.out.println(str);
}

Related

How to reverse an array of characters that make up a sentence

I'm trying to figure out how to take a array of Characters that spell out a sentence backwards (or out of order) with the words separated by spaces to distinguish them and re-order them in the correct/reversed format so instead of the character array spelling out World Good Hello it would spell out Hello Good World like this ['H','e','l','l','o',' ','G','o','o','d',' ','W','o','r','l','d']
This is more or less a shot in the dark.
In the end I would like to return it back as an array of characters.
Code:
class Main {
public static void main(String[] args) {
// World Good Hello
// reverse to: Hello Good World
char[] chrArray = new char[] {'W','o','r','l','d',' ','G','o','o','d',' ','H','e','l','l','o'};
String str = String.valueOf(chrArray);
String[] strArray = str.split(" ");
char[] result = new char[0];
for (int i = 0; i < strArray.length; i++) {
for (int h = 0; h < strArray[i].length(); h++) {
char[] temp = new char[strArray[i].charAt(h)];
temp[temp.length - 1] = ' ';
char[] both = Arrays.copyOf(result, result.length);
List<character> temp2 = System.arraycopy(temp, 0, both, result.length, temp.length);
result = temp2.toCharArray();
}
}
}
}
public static String reverseWords(String sentence) {
String[] words = sentence.split("\\s+");
StringBuilder buf = new StringBuilder(sentence.length());
for (int i = words.length - 1; i >= 0; i--) {
if (buf.length() > 0)
buf.append(' ');
buf.append(words[i]);
}
return buf.toString();
}
Use reverseWords(...).toCharArray() to get char array.
I think the following code would be enough to reverse:
String[] strArray = str.split(" ");
for(int i =strArray.length-1;i>=0;i--) {
System.out.print(strArray[i] + " ");
}
this will output : Hello Good World

Take a List of Strings and double each character in an arraylist

I am trying to double each letter in a list of Strings in an array loop.
For example:
["abc","def"] --> ["aabbcc","ddeeff"]
ArrayList<String> aa;
aa = new ArrayList<String>();
String res = "";
for(int i=0;i<words.size();i++){
char at = aa.get(i);
res=res+at+at;
}
return res;
I am still new to coding and as you can see, my code is a mess. Help is appreciated. Thanks in advance
You some problems with your implementation:
You interact over words array but uses the index over the aa. As it was never added items to it, you will get an ArrayIndexOutOfBoundsException.
You issue a return res but this will return only one string, not an array of words.
According to your example this can be done this way:
public static ArrayList<String> doubleWords(ArrayList<String> input) {
ArrayList<String> result = new ArrayList<>();
for (String string : input) {
String word = "";
for (int i = 0; i < string.length(); i++) {
word += ""+string.charAt(i)+string.charAt(i);
}
result.add(word);
}
return result;
}
Your output for an ArrayList with [abc, def] will be [aabbcc, ddeeff].
You need to iterate through your list of words and then for each word in the list iterate through the characters in the string, like so:
public ArrayList<String> doubleWords(ArrayList<String> words) {
ArrayList<String> doubledWords = new ArrayList<String>();
for (String word : words) {
String newWord = "";
for (int i=0; i<word.length(); i++) {
newWord = newWord + word.substring(i, i+1) + word.substring(i, i+1);
}
doubledWords.add(newWord);
}
return doubledWords;
}
Since Java 8 this can also be achieved in the following way:
String input = "abc";
StringBuilder builder = new StringBuilder();
input.chars().forEach(value -> builder.append((char)value).append((char)value));
Remeber to convert the int value back to a char before you append it.
Output for above program:
System.out.println(builder.toString());
// aabbcc
//response list
ArrayList<String> aa;
aa = new ArrayList<String>();
StringBuilder sb = new StringBuilder() ;
String word;
// iterate list of words
for(int i=0; i < words.size(); i++){
//get word
word = words.get(i);
//iterate each character in word
for(int j =0; j < words; j++) {
//append each char twice in StringBuilder
sb.append(word[j).append(word[j]);
}
//add word to output list
aa.add(sb.toString());
//empty StringBuilder for next word
sb.setLength(0);
}
return aa;
It can be done only by java stream api without any temporary variables:
List<String> result = listOfWords.stream().
map(value -> String.valueOf( // new result String(doubled word)
value.chars() // get chars for each original string
.mapToObj(i-> (char)i) // cast each char from int to char type
.map(c -> String.valueOf(new char[]{c, c})) // create doubled char string
.collect(Collectors.joining()))) // concatenate all doubled chars
.collect(Collectors.toList()); // collect result to list

How can I compare two strings and try to print out comman latters but i could not avoid to repeat a latter more than once

I am comparing two strings and try to print out comman latters but i could not avoid to repeat a latter more than once.
here is my code
public static String getCommonCharacters ( final String a, final String b){
String result="";
for(int i = 0; i < a.length(); i++){
for(int j = 0; j < b.length(); j++)
if(a.charAt(i)==b.charAt(j)){
result +=a.charAt(i);
}
} return result;
the problem is when a = "baac" and b =" fdeabac " then i get out = "aabaac" instead of "abc" or "bca" etc
change the if condition to:
if (a.charAt(i) == b.charAt(j) &&
!result.contains(String.valueOf(a.charAt(i)))) { ... }
Thus, you only perform the statement:
result +=a.charAt(i);
if the accumulating string doesn't already contain the character.
Working code with minor modification to yours:
public class StringCompare {
public static String getCommonCharacters(final String a, final String b) {
String result = "";
for (int i = 0; i < a.length(); i++) {
for (int j = 0; j < b.length(); j++)
if (a.charAt(i) == b.charAt(j)) {
result += a.charAt(i);
}
}
return result;
}
public static void main(String[] args) {
System.out.println(getCommonCharacters("baac", "fdeabac ").replaceAll(
"(.)\\1{1,}", "$1")); // You could use regular expressions for
// that. Removing repeated characters.
}
}
Output:
bac
Pattern explanation:
"(.)\1{1,}" means any character (added to group 1) followed by itself at least once
"$1" references contents of group 1
More about Regular Expressions Oracle Docs
Hier is another solution: create two new HashSet for each String which we change to charArray, then add them to hashSet with For loops,
retainAll() method provide used to remove it's elements from a list that are not contained in the specified collection.#Java Doc by Oracle
Last For-Loop used to concatenate char as a strings.
String str ="";
Set<Character> s1 = new HashSet<Character>();
Set<Character> s2 = new HashSet<Character>();
for(char c:a.toCharArray()) s1.add(c);
for(char c:b.toCharArray()) s2.add(c);
s1.retainAll(s2);
for(char s:s1) str +=s;
return str;

Java - make new string based on old one and lag

I need to get a new string based on an old one and a lag. Basically, I have a string with the alphabet (s = "abc...xyz") and based on a lag (i.e. 3), the new string should replace the characters in a string I type with the character placed some positions forward (lag). If, let's say, I type "cde" as my string, the output should be "fgh". If any other character is added in the string (apart from space - " "), it should be removed. Here is what I tried, but it doesn't work :
String code = "abcdefghijklmnopqrstuvwxyzabcd"; //my lag is 4 and I added the first 4 characters to
char old; //avoid OutOfRange issues
char nou;
for (int i = 0; i < code.length() - lag; ++i)
{
old = code.charAt(i);
//System.out.print(old + " ");
nou = code.charAt(i + lag);
//System.out.println(nou + " ");
// if (s.indexOf(old) != 0)
// {
s = s.replace(old, nou);
// }
}
I commented the outputs for old and nou (new, but is reserved word) because I have used them only to test if the code from position i to i + lag is working (and it is), but if I uncomment the if statement, it doesn't do anything and I leave it like this, it keeps executing the instructions inside the for statmement for code.length() times, but my string doesn't need to be so long. I have also tried to make the for statement like below, but I got lost.
for (int i = 0; i < s.length(); ++i)
{
....
}
Could you help me with this? Or maybe some advices about how I should think the algorithm?
Thanks!
It doesn't work because, as the javadoc of replace() says:
Returns a new string resulting from replacing all occurrences of oldChar in this string with newChar.
(emphasis mine)
So, the first time you meet an 'a' in the string, you replace all the 'a's by 'd'. But then you go to the next char, and if it's a 'd' that was an 'a' before, you replace it once again, etc. etc.
You shouldn't use replace() at all. Instead, you should simply build a new string, using a StringBuilder, by appending each shifted character of the original string:
String dictionary = "abcdefghijklmnopqrstuvwxyz";
StringBuilder sb = new StringBuilder(input.length());
for (int i = 0; i < input.length(); i++) {
char oldChar = input.charAt(i);
int oldCharPositionInDictionary = dictionary.indexOf(oldChar);
if (oldCharPositionInDictionary >= 0) {
int newCharPositionInDictionary =
(oldCharPositionInDictionary + lag) % dictionary.length();
sb.append(dictionary.charAt(newCharPositionInDictionary));
}
else if (oldChar == ' ') {
sb.append(' ');
}
}
String result = sb.toString();
Try this:
Convert the string to char array.
iterate over each char array and change the char by adding lag
create new String just once (instead of loop) with new String passing char array.
String code = "abcdefghijklmnopqrstuvwxyzabcd";
String s = "abcdef";
char[] ch = s.toCharArray();
char[] codes = code.toCharArray();
for (int i = 0; i < ch.length; ++i)
{
ch[i] = codes[ch[i] - 'a' + 3];
}
String str = new String(ch);
System.out.println(str);
}
My answer is something like this.
It returns one more index to every character.
It reverses every String.
Have a good day!
package org.owls.sof;
import java.util.Scanner;
public class Main {
private static final String CODE = "abcdefghijklmnopqrstuvwxyz"; //my lag is 4 and I added the first 4 characters to
#SuppressWarnings("resource")
public static void main(String[] args) {
System.out.print("insert alphabet >> ");
Scanner scanner = new Scanner(System.in);
String s = scanner.next();
char[] char_arr = s.toCharArray();
for(int i = 0; i < char_arr.length; i++){
int order = CODE.indexOf(char_arr[i]) + 1;
if(order%CODE.length() == 0){
char_arr[i] = CODE.charAt(0);
}else{
char_arr[i] = CODE.charAt(order);
}
}
System.out.println(new String(char_arr));
//reverse
System.out.println(reverse(new String(char_arr)));
}
private static String reverse (String str) {
char[] char_arr = str.toCharArray();
for(int i = 0; i < char_arr.length/2; i++){
char tmp = char_arr[i];
char_arr[i] = char_arr[char_arr.length - i - 1];
char_arr[char_arr.length - i - 1] = tmp;
}
return new String(char_arr);
}
}
String alpha = "abcdefghijklmnopqrstuvwxyzabcd"; // alphabet
int N = alpha.length();
int lag = 3; // shift value
String s = "cde"; // input
StringBuilder sb = new StringBuilder();
for (int i = 0, index; i < s.length(); i++) {
index = s.charAt(i) - 'a';
sb.append(alpha.charAt((index + lag) % N));
}
String op = sb.toString(); // output

Checking to see whether a string has certain characters in alphabetical order

I have to check a word/phrase and say whether the vowels in it are in alphabetical or reverse alphabetical order.
Im so close to getting it. Its just the final bit comparing the numbers in the array, to see whether or not they are in descending order etc. I know I have to make a nested for loop but Im not sure exactly how to do it. Thanks for the help.
public static void main(String [] args)
{
String result = "", result2="";
String userInput = "aeiou";
int [] array = new int[userInput.length()];
for(int i = 0; i < string.length(); ++i)
{
char c = replace.charAt( i );
int j = (int) c;
array[i] = j;
//printing unicode symbols (only for testing)
result2 += array[i] +",";
System.out.println(j);
}
boolean sequence = false;
for(int i = 0; i <array.length-1 && !sequence; i++)
{
for(int x =i+1; x<array.length; x++)
{
//Here I am checking to see whether or not they are in alphabetical order
if(array[i] < array[x])
sequence = true;
if(sequence == true)
result = "The vowels are in alphabetical order";
else
result = "The vowels are not in alphabetical order";
}
}
System.out.println(result);
}
Since you are using replaceAll(), I assume you can also use matches() (replace is the variable that contains the string after you replace everything but the vowels):
boolean isAscending = replace.matches("a*e*i*o*u*");
boolean isDescending = replace.matches("u*o*i*e*a*");
Well, there are some special cases here that doesn't seem to be considered in your code:
String in replace variable is empty (no vowel)
Only contains one vowel being repeated (e.g. pool --> oo)
In both cases above, isAscending and isDescending will both be true.
try
String input = "abc";
char[] a = input.toCharArray();
Arrays.sort(a);
StringBuilder sb = new StringBuilder();
sb.append(a);
if (input.equals(sb.toString())) {
System.out.println("ascending");
} else if (input.equals(sb.reverse().toString())) {
System.out.println("descending");
} else {
System.out.println("unsorted");
}

Categories

Resources