This question already has answers here:
Reverse a given sentence in Java
(14 answers)
Closed 9 years ago.
I m inserting a string in my program
String str = " I live in India";
how can in get reversed string of that like
String str ="India in live I"
this is an interview question in my interview. Please any one can help me out in this question
Split it and then add it to a new String in reverse order.
String s = " I live in India";
String[] split = s.split(" ");
String result = "";
for (int i = split.length - 1; i >= 0; i--) {
result += (split[i] + " ");
}
System.out.println(result.trim());
This prints:
India in live I
Although short and straight-forward, this solution is not really effective in terms of time and memory. It somewhat depends on how the input is given (as a String or as something else) and whether we can modify the input in order to save computation resources.
Let's assume the sentence is given as an array of characters and we are allowed to modify it. We can then follow the following approach, which brings linear time (O(n)) and constant (O(1)) memory complexity:
What we will have as input would be:
char[] array = {'I',' ','l','i','v','e',' ','i','n',' ','I','n','d','i','a'};
Let's write a method that takes a char[] array and reverses the elements from start to end in-place:
void reverse(char[] array, int start, int end) {
while (start < end) {
char temp = array[start];
array[start] = array[end];
array[end] = temp;
start++;
end--;
}
}
First, we will reverse the whole array (in-place), using this method.
You can notice that after the reversal the words in the sentence are ordered in the desired (reversed) way. The problem is that each word is reversed:
{'a','i','d','n','I',' ','n','i',' ','e','v','i','l',' ','I'}
Let's now iterate the array from left to the right. We will reverse each word in-place, like we initially reversed the whole array. In order to do that, we need to keep an index (start), telling where does a word start and every time we encounter a space (' ') we will trigger a reverse between start and the character before the space. This way we will keep the desired order of words, but we will also have the characters in the words properly ordered.
The code should be self-explanatory:
void reverseSentence(char[] array) {
int n = array.length;
reverse(array, 0, n - 1);
int start = 0;
for (int i = 0; i < n; i++) {
if (array[i] == ' ') {
reverse(array, start, i - 1);
start = i + 1;
}
}
}
Calling this on the initial array, we get:
{'I','n','d','i','a',' ','i','n',' ','l','i','v','e', ' ','I'}
We can further construct a String out of it, or just print it. In any case, the sentence is reversed as desired.
This has linear complexity (O(n)), because each character is part of a reverse exactly once and is being tested for being a space exactly once.
As for memory-usage, we used only one additional variable (start), which makes the total memory complexity a constant (O(1)).
String str = "I live in India";
String result = "";
String[] words = str.split(" ");
for (int i=words.length-1;i>=0;i--){
result = result + words[i] + " ";
}
result = result.subString(result, 0, result.length-1); // remove the last " "
This code splits the String along the whitespaces, so that you get an array of the words.
Then a for loop iterates through the array from last to first element and appends the words plus a whitespace to the result string. Finally the whitepace after the last word is removed.
try this way
public class test {
public static void main(String args[])
{
String x="i live in india";
String y[]=x.split(" ");
System.out.println(y[3]+" "+y[2]+" "+y[1]+" "+y[0]);
// if the input string is different meaning if the number of words are greater than or less than four then try this way
/*for(int i=y.length-1;i>=0;i--)
{
System.out.print(y[i]+ " ");
}*/
}
}
this is the screenshot to show the output
Related
The code below works when number of strings in array is odd (3,5,7) however it does not work when the number is even. For example, if I use "my is the name" I get output
name is the name
public void randomTest() {
String str ="my is name";
//Step1: split so that I can get them in in array
String [] arrStr= str.split(" ");
for(int i=0;i<arrStr.length;i++){
//Step2: Using temp swap 1st and last
String temp = arrStr[0];
arrStr[0] = arrStr[arrStr.length-1];
arrStr[arrStr.length-1] = temp;
System.out.print(arrStr[i]+" ");
}
}
Any idea how can I make it work for even number of Strings? Thank You.
Since Arvind Kumar Avinash has shared the fixed solution, I just like to offer an alternative option: After splitting the string into String array, maybe you can simply swap the last and first values, and then join them together:
String str ="my is the name";
// split
String[] arrStr= str.split(" ");
// swap
String temp = arrStr[0];
arrStr[0] = arrStr[arrStr.length - 1];
arrStr[arrStr.length - 1] = temp;
// join them back
str = String.join(" ", arrStr);
System.out.println(str); // name is the my
You need to iterate the loop only for half of the length of the array i.e.
for (int i = 0; i < arrStr.length / 2; i++)
Also, you need to use the counter variable, i instead of the fixed values 0 and 1. Make sure to limit the indices in the range of 0 to length_of_array - 1 which is the range of indices of an array in Java.
Do it as follows:
public class Main {
public static void main(String[] args) {
String str = "my is the name";
String[] arrStr = str.split(" ");
// Swap the elements of the array
for (int i = 0; i < arrStr.length / 2; i++) {
String temp = arrStr[i];
arrStr[i] = arrStr[arrStr.length - i - 1];
arrStr[arrStr.length - i - 1] = temp;
}
// Display the array
for (int i = 0; i < arrStr.length; i++) {
System.out.print(arrStr[i] + " ");
}
}
}
Output:
name the is my
If you want to swap only the first word with the last word, you do not need a loop. You can simply so it as follows:
public class Main {
public static void main(String[] args) {
String str = "my is the name";
String[] arrStr = str.split(" ");
// Swap the first and the last words
String temp = arrStr[0];
arrStr[0] = arrStr[arrStr.length - 1];
arrStr[arrStr.length - 1] = temp;
// Display the array
for (int i = 0; i < arrStr.length; i++) {
System.out.print(arrStr[i] + " ");
}
}
}
Output:
name is the my
What you are currently doing is swapping the first and last elements n times, where n is the size of the array. This makes it so that when you have an even number of elements, for example, 2, then you are swapping the first and last elements, and then swapping them back to their original position, which is unswapped. This is also why it is working for an odd number of elements since you are swapping the first and last elements an even number of times and then once more. If you just want to swap the first and last elements, you can simply get rid of the for loop that you have and it will work properly.
public void randomTest() {
String str ="my is name";
//Step1: split so that I can get them in in array
String [] arrStr= str.split(" ");
//Step2: Using temp swap 1st and last
String temp = arrStr[0];
arrStr[0] = arrStr[arrStr.length-1];
arrStr[arrStr.length-1] = temp;
}
Afterwards, if you want to merge the strings back together, you can use
str = String.join(" ", arrStr);
or a StringBuilder object like so.
StringBuilder sb = new StringBuilder(arrStr[0]);
for (int i = 0; i < arrStr.length; i++) {
sb.append(" ").append(arrStr[i]);
}
str = sb.toString();
The effect of either of these will turn my name is foo into foo name is my, basically swapping the first and last words, and will work for a string with any length or number of words.
Easiest way is to substring first and last word from the sentence.
int first = name.indexOf(' '); // first "space" character that occurs
int last = name.lastIndexOf(' '); // last "space" character that occurs
String firstWord = name.substring(0, first); // substring first word from index 0 to index of first "space" character
String lastWord = name.substring(last, name.length()-1); // substring last word from index the of last "space" character to higher index o sentence
String midSentece = name.substring(first, last); // substring rest of the sentence
System.out.println(lastWord + midSentece + firstWord);
I know similar questions have been asked. I've read through them and have developed what I thought was a reasonable solution to my problem. However, when I run the code it does not perform as I think it should. I'm obviously missing something here.
I need to read in a string (a propositional logic statement) and determine how many variables it has. My thought process is: convert the string to a charArray and compare the elements. If a certain element is a letter AND is not equal to another element in the array, it is a new variable, thus adding to the variable count, and also needs to be stored in a separate array for later use.
public class PropLogic {
public static void main(String[] args) {
Scanner stdin = new Scanner(System.in);
String statement;
int numOfVariables = 0;
System.out.println("Enter your propositional statement:");
statement = stdin.nextLine();
char[] charStatement = statement.toCharArray();
char[] variables;
variables = new char[25];
// Counts number of variables in statement
for (int i = 0; i < statement.length(); i++){
for(int j = i + 1; j < statement.length(); j++){
if(Character.isLetter(charStatement[i]) && (charStatement[i] !=
charStatement[j])){
variables[i] = charStatement[i];
numOfVariables++;
}
}
}
System.out.println("The number of variables is " + numOfVariables);
System.out.println("The variables are " + new String(variables));
}}
With input "hello" I get output of 9 variables and that the variables are "hell" when I want to be getting 4 variables that are "hello".
Why don't you use a Set. A set has the property that you can enter the same object only once into it. Here is one version:
Set<Character> set = new LinkedHashSet<>();
for(int i = 0; i< statement.length(); i++) {
set.add(statement.charAt(i));
}
System.out.println("The number of variables is " + set.size());
System.out.println("The variables are ");
set.forEach(System.out::println);
You don't need to use char array since String has the methods CharAt() and contains().
Then you have to run through your String. When you find a new letter (which mean this letter is not in the already found array), you put it in the already found array and you increment your counter. (note that the counter is useless since it as the same value as the length of the already found array). You should obtain something like this :
String statement = stdin.nextLine();
String variables = ""; //empty String
//Go through the whole String statement
for (int i = 0; i < statement.length(); i++){
//Check if this letter was not already found and it's a letter
if(!variables.contains(statement.charAt(i)) && Character.isLetter(statement.charAt(i)) ){
//Add this letter to the found ones
variables.concat(String.valueOf(statement.charAt(i)));
}
}
System.out.println("The number of variables is " + variables.length());
System.out.println("The variables are " + variables);
I see two problems:
Problem 1. Think about what happens, for example, with the "h" of "hello." You compare it, in turn, to "e", "l", "l", and "o", and for each of them, you add a new variable. What you want is to add a new variable only if ALL of the future letters are not equal to the "h." This is why you are getting 9 variables total: you add one for each of the following comparisons:
(h, e), (h, l), (h, l), (h, o)
(e, l), (e, l), (e, o)
(l, o)
(l, o)
This is also why you are getting "hell" as your final variables array. The o is never compared to anything, so never gets added to the array.
What you really want to do is go through the entire rest of the string, and check if anything is equal to the current letter. You can do this with a boolean flag. Here is pseudocode:
for i = 0 to len(charArray):
isNewVariable = isLetter(charArray[i])
for j = i+1 to len(charArray):
if charArray[i] == charArray[j]:
isNewVariable = false
if isNewVariable:
Add charArray[i] to variables
Problem 2. You are filling in the wrong index of your variables array. You want to fill in variables[numOfVariables], not variables[i]. Let's say the first and seventh letters are variables; then you want variables[0] and variables[1] to be set to the two variables, not variables[0] and variables[6], which is what your current code does.
Hope this helps! If you fix these two errors, your code will work; however, as other answers point out, this general strategy is not the best for this specific task. Incrementally adding to an array (like variables) is best done with an ArrayList; even better, a Set is exactly suited for the task of finding just the unique elements of an array.
what is happening here is, check if char exists in temp string with 'temp.indexOf(char)', it returns 1 if it exists at an index of that string and 0 otherwise.
so if 0, then add and loop to next char.
public static void main( String[] args ){
Scanner stdin = new Scanner(System.in);
String statement;
int numOfVariables = 0;
System.out.println("Enter your propositional statement:");
statement = stdin.nextLine();
char[] charStatement = statement.toCharArray();
char[] variables;
variables = new char[25];
String temp = "";
for (int i = 0; i < statement.length(); i++){
char current = statement.charAt(i);
if (temp.indexOf(current) < 0){
temp = temp + current;
}
}
System.out.println("The number of variables is " + temp.length());
System.out.println("The variables are " + temp);
}
A key to success in writing good programs is to make sure it has as few lines of code as possible and it doesn't repeat an operation that it has already performed or that is not even needed.
If you think about your problem statement, basically, all you need to do is extract letters from a given input string and remove duplicates. With advance programming languages like Java, String operations shouldn't take more than a couple of lines of codes. If it is more than 2 lines, in most cases, it has a lot of boiler plate code.
See if the following line of code meets your objective.
Set<String> variables = Arrays.stream(statement.split("")).filter(str -> Character.isLetter(str.charAt(0))).collect(Collectors.toSet());
If you are OK with not insisting on char[] variables and use List<Character> instead, this does the job
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class PropLogic {
public static List<Character> parseVariables(char[] input) {
List<Character> candidates = new ArrayList<>();
for (int i = 0; i < input.length; i++){
Character c = input[i];
if( Character.isLetter(c) && !candidates.contains(c)) {
candidates.add(c);
}
}
return candidates;
}
public static void main(String[] args) {
Scanner stdin = new Scanner(System.in);
System.out.println("Enter your propositional statement:");
char[] charStatement = stdin.nextLine().toCharArray();
List<Character> variables = parseVariables(charStatement);
System.out.println("The number of variables is " + variables.size());
System.out.println("The variables are " + variables);
}
}
Sample output:
Enter your propositional statement:
hello1
The number of variables is 4
The variables are [h, e, l, o]
Here's a 1-liner:
String[] variables = statement.replaceAll("[^a-z]|(.)(?=.*\\1)", "").split("(?<=.)");
This uses regex to remove (by replacing with a blank) all non-lowercase letters OR all letters that are repeated later on (ie remove dupes).
Then it splits after each letter giving you the final array of unique letters from the input.
Note that this creates a String[] rather than a char[], which you can just as easily use. If you really want a char[], you can do this:
String[] variables = statement.replaceAll("[^a-z]", "").chars()
.distinct().mapToObject(c -> (char)c).toArray();
I have large text files and they each contain strings of words and numbers.
I need to increase those numbers by a fixed value and write them right back to where they were before within that string.
The value that I want to add depends on the word that came before the number, and every number that has none of these keywords must not be increased.
My approach would be to split at space characters, check for the words and handle the digit after, whenever I find the keyword. However, this leaves me with the requirement of having space characters between word and number and that is not ensured.
Furthermore, when reassembling the string from the split array, this might break the layout from before.
An example could be
"Mark is quite large, 189cm, and was born in the year 1978. However, he has only 1 question concerning parsing, that he really can't get his head around."
After large, the height should be increased by 5 and after year, the number subtracted by 19. The number 1 should stay untouched, as only is not a keyword.
I can work with both, java or python, as these are the languages I know.
I think i got something:
public class Start {
public static void main(String[] args){
//Test String
String s = "not4inc6desc3inc14";
StringBuffer sb = new StringBuffer(s);
//keep track where new word begins
int newWord = 0;
for(int i = 0; i < sb.length(); i++){
//chekc if the new Character is a number
if(checkNumber(sb.substring(i, i+1))){
//if the old word ends with "inc"
//maybe try out .contains()
if(sb.substring(newWord, i).endsWith("inc")){
//replace number
StringBuffer temp = new StringBuffer();
int j = 0;
//get full number
for(j = i; j < sb.length() && checkNumber(sb.substring(j, j+1)); j++){
temp.append(sb.substring(j, j+1));
}
//modify number
int number = Integer.parseInt(temp.toString()) + 1;
//replace number
sb.replace(i, i + temp.length(), Integer.toString(number));
//number no longer needs to be checked for being a word
i=j;
}
}
}
//print test String
System.out.println(sb.toString());
}
// Check if String is numeric
private static boolean checkNumber(String s){
try{
Integer.parseInt(s);
}catch(NumberFormatException e ){
return false;
}
return true;
}
}
I'm sorry it's a bit hard to understand... feel free to ask...
So I am a beginner in Java and was solving from a book where the question was :
Write a program that sets up a String variable containing a paragraph
of text of your choice. Extract the words from the text and sort them
into alphabetical order. Display the sorted list of words. You could
use a simple sorting method called the bubble sort. To sort an array
into ascending order the process is as follows: a. Starting with the
first element in the array, compare successive elements (0 and 1, 1
and 2, 2 and 3, and so on). b. If the first element of any pair is
greater than the second, interchange the two elements. c. Repeat the
process for the whole array until no interchanges are necessary. The
array elements are now in ascending order.
To which my solution was:
public class bubbleSort {
public static void main(String[] args) {
String Homer = "He was the son of Epikaste and Telemachus. " +
"He was said to be a court singer ";
String swap;
Homer = Homer.replace(',', ' ');
Homer = Homer.replace('.', ' ');
Homer = Homer.replace(" ", " ");
String[] words = Homer.split(" ");
for(String val:words){
System.out.println(val);
}
System.out.println(" ---- SORTED -------");
boolean exchange = true;
while (exchange) {
exchange = false;
for (int i = 0; i < (words.length - 1); ++i) {
if (words[i].charAt(0) > words[i + 1].charAt(0)) {
swap = words[i];
words[i] = words[i + 1];
words[i + 1] = swap;
exchange = true;
}
}
}
for(String val:words){
System.out.println(val);
}
}
}
However the sorted output wasn't as intended !
He was the son of Epikaste and Telemachus He was said to be a court
singer ---- SORETED ------- Epikaste He He Telemachus and a be court
of son said singer the to was was
Where have I made a mistake? Thanks !
The simple way would be to convert all words to upper or lower case.
However, the correct way to compare words of a language in Java is to use the Collator
Collator myCollator = Collator.getInstance(); // optional: pass your locale
if( myCollator.compare("abc", "ABC") < 0 )
System.out.println("abc is less than ABC");
else
System.out.println("abc is greater than or equal to ABC");
This makes sure that words with special characters like 'è' or 'ä' are sorted correctly. While this makes no difference for your example, if you are learning Java, learn it right from the start.
In your example, create a collator instance at the beginning of the method and replace
if (words[i].charAt(0) > words[i + 1].charAt(0))
with
if (myCollator.compare(words[i], words[i+1]) > 0)
It is sorted Capital letters are less than lower case letters in ascii to get the correct sorting change all the capitals to lower case or vise versa while sorting
I guess what you don't like in the result is that it sorted uppercase (capitalized) words before lowercase words. This is not surprising, because uppercase characters A-Z use the code points 65 through 90, whereas lowercase chars a-z have code points 97 through 122. So uppercase chars are always "smaller" than lowercase chars in a comparision.
Solution: Convert all words to lowercase for the comparison. Use String.toLowerCase() for that.
For example, instead of your original code
for (int i = 0; i < (words.length - 1); ++i) {
if (words[i].charAt(0) > words[i + 1].charAt(0)) {
do it more like
for (int i = 0; i < (words.length - 1); ++i) {
String w = words[i].toLowerCase();
String w1 = words[i+1].toLowerCase();
if (w.charAt(0) > w1.charAt(0)) {
This question already has answers here:
Java compressing Strings
(21 answers)
Closed 8 years ago.
I am trying to write a Java program which takes in as input a string and counts the number of occurrences of characters in a string and then prints a new string having the character followed by the no of occurrences.
E.G.
Input String:
aaaabb
Output String:
a4b2
Input String:
aaaaabbbc
Output String:
a5b3c1
I am posting my java code.
It is throwing StringOutOfBoundException
/*Write a routine that takes as input a string such as "aabbccdef" and o/p "a2b2c2def" or "a4bd2g4" for "aaaabddgggg".*/
import java.util.Scanner;
public class CountingOccurences {
public static void main(String[] args) {
Scanner inp= new Scanner(System.in);
String str;
char ch;
int count=0;
System.out.println("Enter the string:");
str=inp.nextLine();
while(str.length()>0)
{
ch=str.charAt(0);
int i=0;
while(str.charAt(i)==ch)
{
count =count+i;
i++;
}
str.substring(count);
System.out.println(ch);
System.out.println(count);
}
}
}
This is the problem:
while(str.charAt(i)==ch)
That will keep going until it falls off the end... when i is the same as the length of the string, it will be asking for a character beyond the end of the string. You probably want:
while (i < str.length() && str.charAt(i) == ch)
You also need to set count to 0 at the start of each iteration of the bigger loop - the count resets, after all - and change
count = count + i;
to either:
count++;
... or get rid of count or i. They're always going to have the same value, after all. Personally I'd just use one variable, declared and initialized inside the loop. That's a general style point, in fact - it's cleaner to declare local variables when they're needed, rather than declaring them all at the top of the method.
However, then your program will loop forever, as this doesn't do anything useful:
str.substring(count);
Strings are immutable in Java - substring returns a new string. I think you want:
str = str.substring(count);
Note that this will still output "a2b2a2" for "aabbaa". Is that okay?
public class StringTest{
public static void main(String[] args){
String s ="aaabbbbccccccdd";
String result="";
StringBuilder sb = new StringBuilder(s);
while(sb.length() != 0){
int count = 0;
char test = sb.charAt(0);
while(sb.indexOf(test+"") != -1){
sb.deleteCharAt(sb.indexOf(test+""));
count++;
}
//System.out.println(test+" is repeated "+count+" number of times");
result=result+test+count;
}
System.out.println(result);
}
}
I don't want to give out the full code. So I want to give you the challenge and have fun with it. I encourage you to make the code simpler and with only 1 loop.
Basically, my idea is to pair up the characters comparison, side by side. For example, compare char 1 with char 2, char 2 with char 3, and so on. When char N not the same with char (N+1) then reset the character count. You can do this in one loop only! While processing this, form a new string. Don't use the same string as your input. That's confusing.
Remember, making things simple counts. Life for developers is hard enough looking at complex code.
Have fun!
Tommy "I should be a Teacher" Kwee
if this is a real program and not a study project, then look at using the Apache Commons StringUtils class - particularly the countMatches method.
If it is a study project then keep at it and learn from your exploring :)
You should be able to utilize the StringUtils class and the countMatches() method.
public static int countMatches(String str,
String sub)
Counts how many times the substring appears in the larger String.
Try the following:
int count = StringUtils.countMatches("a.b.c.d", ".");
I think what you are looking for is this:
public class Ques2 {
/**
* #param args the command line arguments
*/
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String input = br.readLine().toLowerCase();
StringBuilder result = new StringBuilder();
char currentCharacter;
int count;
for (int i = 0; i < input.length(); i++) {
currentCharacter = input.charAt(i);
count = 1;
while (i < input.length() - 1 && input.charAt(i + 1) == currentCharacter) {
count++;
i++;
}
result.append(currentCharacter);
result.append(count);
}
System.out.println("" + result);
}
}
Try this:
import java.util.Scanner;
/* Logic: Consider first character in the string and start counting occurrence of
this character in the entire string. Now add this character to a empty
string "temp" to keep track of the already counted characters.
Next start counting from next character and start counting the character
only if it is not present in the "temp" string( which means only if it is
not counted already)
public class Counting_Occurences {
public static void main(String[] args) {
Scanner input=new Scanner(System.in);
System.out.println("Enter String");
String str=input.nextLine();
int count=0;
String temp=""; // An empty string to keep track of counted
// characters
for(int i=0;i<str.length();i++)
{
char c=str.charAt(i); // take one character (c) in string
for(int j=i;j<str.length();j++)
{
char k=str.charAt(j);
// take one character (c) and compare with each character (k) in the string
// also check that character (c) is not already counted.
// if condition passes then increment the count.
if(c==k && temp.indexOf(c)==-1)
{
count=count+1;
}
}
if(temp.indexOf(c)==-1) // if it is not already counted
{
temp=temp+c; // append the character to the temp indicating
// that you have already counted it.
System.out.println("Character " + c + " occurs " + count + " times");
}
// reset the counter for next iteration
count=0;
}
}
}