So I'm currently working on a personal project and I made a program that tries to swap every 2 letter in a given string.
So I want the output like this:
(Note Input String is "abllte")
ballet
So I wrote this method
public static String codeString(String input) {
String firstLetter = "";
String secoundLetter = "";
String result = "";
for(int i = 0; i < input.length()-1; i++){
for(int c = 0; c < i; c = c +2)
{
firstLetter = input.substring(c,c + 1);
secoundLetter = input.substring(c + 1, c + 2);
}
result = result + secoundLetter + firstLetter;
}
return result;
}
But I get this output:
ababllll
Any idea how to solve this?
Thank you in advance!
You only need one loop. This works for both even and odd length character strings.
first, the methods used return the StringBuilder in its current modified state.
So sb.insert(i, sb.charAt(i+1)) inserts the char at i+1 at i
So if sb contained ab, StringBuilder would now contain bab
insert returns the modifed StringBuilder so now sb.deleteCharAt(i+2) deletes the second a (the one that was just copied).
this is then repeated until all characters are swapped.
Because of the constant inserting and deletion of characters this is not very efficient.
for (String s : new String[] { "abcdefg", "abcdefgh" }) {
StringBuilder sb = new StringBuilder(s);
for (int i = 0; i < sb.length() - 1; i += 2) {
sb.insert(i, sb.charAt(i + 1)).deleteCharAt(i + 2);
}
System.out.println(s + " -> " + sb);
}
Prints
abcdefg -> badcfeg
abcdefgh -> badcfehg
For a more efficient algorithm, this would be the way to go. It's also much more intuitive.
for (String s : new String[] { "abcdefg", "abcdefgh" }) {
char ch[] = s.toCharArray();
for (int i = 0; i < ch.length - 1; i+=2) {
char c = ch[i];
ch[i] = ch[i + 1];
ch[i + 1] = c;
}
String d = String.valueOf(ch);
System.out.println(s + " -> " + d);
}
This prints the same as above.
I'm not sure what the point of your nested for loop is. You can do this with just one loop.
public static String codeString(String input) {
String firstLetter = "";
String secoundLetter = "";
String result = "";
for(int i = 0; i < input.length()-1; i+=2){
firstLetter = input.substring(i,i+1);
secoundLetter = input.substring(i+1,i+2);
result = result + secoundLetter + firstLetter;
}
return result;
}
If your input string has an odd number of characters, you'll have to append the extra last character.
public static String codeString(String input) {
String firstLetter = "";
String secoundLetter = "";
String result = "";
for(int i = 0; i < input.length()-1; i+=2){
firstLetter = input.substring(i, i+1);
secoundLetter = input.substring(i+1, i+2);
result = result + secoundLetter + firstLetter;
}
if(input.length() % 2 == 1)
result += input.substring(input.length()-1, input.length());
return result;
}
You do not need a nested loop. Change the outer loop to step by 2 i.e. i = i + 2 and remove the inner loop.
public class Main {
public static void main(String[] args) {
System.out.println(codeString("abllte"));
}
public static String codeString(String input) {
String firstLetter = "";
String secondLetter = "";
String result = "";
for (int i = 0; i < input.length() - 1; i = i + 2) {
firstLetter = input.substring(i, i + 1);
secondLetter = input.substring(i + 1, i + 2);
result = result + secondLetter + firstLetter;
}
return result;
}
}
Output:
ballet
An alternative approach:
You can create a function with two parameters: input string as the first parameter and n as the second parameter, where every n characters in the input string need to be reversed.
public class Main {
public static void main(String[] args) {
System.out.println(codeString("abllte", 1));
System.out.println(codeString("abllte", 2));
System.out.println(codeString("abllte", 3));
System.out.println(codeString("abllte", 4));
}
public static String codeString(String input, int n) {
if (n <= input.length() / 2) {
StringBuilder result = new StringBuilder();
for (int i = 0; i < input.length() - n + 1; i = i + n) {
result.append(new StringBuilder(input.substring(i, i + n)).reverse());
}
return result.toString();
} else {
return input;
}
}
}
Output:
abllte
ballet
lbaetl
abllte
Related
I have a String , String a = newNumber + "*" + nn + "+" + difference;
the newNumber = 106 , nn = 3 and difference = 3.
so the output should be as follow ;
Output :
106*3+3
I would like to modify the String so that the output becomes (35*3+1)*3+3 and then with this new String I would like to modify it again so that it becomes ((11*3+2)*3+1)*3+3
Basically I just need to replace the newNumber which was 106 and kept changing to 11, as you can see I'm trying to modify only the newNumber and replacing it with another while keeping the entire String untouched , I'm just replacing and adding to it , how can this be achieved ?
The output should be like this,
Output :
106*3+3
(35*3+1)*3+3
((11*3+2)*3+1)*3+3
I'm solving an equation with steps , the formulas don't matter I'm just trying to figure out how can I modify the String by replacing the newNumber with a another number and adding new brackets to the equation.
I hope I wrote my problem in a way you would understand , I'd really appreciate the help.
I could not get to the same output which you have but here the code which try to solve this problem I think it might give you little help though which you could solve the problem.
Breaking the number until its prime number and adding the prime numbers to the result. Since we are replacing and appending with strings its better to use StringBuilder.
import java.io.PrintStream;
import java.util.Arrays;
public class StringSimplification {
public static PrintStream out = System.out;
public static final boolean prime[];
public static final int SIZE = 1000000;
static {
prime = new boolean[SIZE];
Arrays.fill(prime, true);
prime[0] = prime[1] = false;
//Sieve of Eratosthenes algorithm to find weather number is prime
for (int i = 2; i < SIZE; i++)
if (prime[i])
for (int j = i * 2; j < SIZE; j += i)
prime[j] = false;
}
//simplifies your String expression
public static String simplify(final String expression) {
StringBuilder result = new StringBuilder("");
String exp = "";
for (char ch : expression.toCharArray()) {
if (Character.isDigit(ch))
exp += ch;
else {
if (isNumber(exp)) {
String simplified = getExpression(Integer.parseInt(exp));
result.append(simplified+ch);
exp = "";//clearing exp
};
}
}
result.append(exp);
return result.toString();
}
//returns weather number is prime or not
static boolean isPrime(final int val) {
return prime[val];
}
static String getExpression(final int val) {
if (val == 0 || val == 1 || prime[val])
return "(" + val + ")";
int prev = 1;
int div = 1;
for (int i = 1; i < val; i++) {
if (val % i == 0) {
prev = i;
div = val / i;
}
}
return getExpression(prev) + "*" + getExpression(div);
}
//Check's weather the expression is number
public static boolean isNumber(final String s) {
for (var c : s.toCharArray())
if (!Character.isDigit(c))
return false;
return s.length() > 0;
}
public static void main(final String... $) {
out.println(simplify("106*3+3"));
out.println(simplify("1024*3+3"));
}
}
Output:
(53)*(2)*(3)+3
(2)*(2)*(2)*(2)*(2)*(2)*(2)*(2)*(2)*(2)*(3)+3
You can’t actually modify Strings, but you can use replaceFirst() like this:
s = s.replaceFirst("106", "(35*3+1)");
s = s.replaceFirst("35", "(11*3+2)");
etc
Strings in java are immutable. You will have to use StringBuilder or String Buffer
However if you insist then you may try(from what I understood of the pattern)
int num = 106;
String rep = "";
String S = "106*3+3";
String target;
int b = 1;
int largestfactor = 1;
System.out.println(S);
for (int i = num; i > 0; i--) {
for (int j = 1; j < (num - b); j++) {
if ((num - b) % j == 0)
largestfactor = j;
}
target = "" + num;
rep = "(" + largestfactor + "*" + (num - b) / largestfactor + ")" + "+" + b;
S = S.replace(target,rep);
System.out.println(S);
num = largestfactor;
b++;
if(b>num)
break;
}
I have a String:
String example = "AA5DD2EE3MM";
I want to replace the number with the number of spaces. Example:
String example = "AA DD EE MM"
If the String would be
String anotherExample = "a3ee"
It should turn into:
String anotherExample = "a ee"
I want to do it for any string. Not only for the examples above.
Split your input at digit and non digit chars as a stream, map digits to the corsponding number of spaces using String.repeat, collect to string using Collectors.joining():
String input = "AA5DD2EE3MM";
String regex = "(?<=\\D)(?=\\d)|(?<=\\d)(?=\\D)";
String result = Pattern.compile(regex)
.splitAsStream(input)
.map(s -> s.matches("\\d+") ? " ".repeat(Integer.parseInt(s)) : s)
.collect(Collectors.joining());
You could also use this approach, which is simpler but also far less elegant:
String example = "a4aa";
String newString = "";
for (int i = 0; i < example.length(); i++) {
if (Character.isDigit(example.charAt(i))) {
for (int a = 0; a < Character.getNumericValue(example.charAt(i)); a++) {
newString += " ";
}
} else {
newString += example.charAt(i);
}
}
System.out.println(newString);
Using a pattern matcher approach:
String input = "AA5DD2EE3MM";
Pattern pattern = Pattern.compile("\\d+");
Matcher m = pattern.matcher(input);
StringBuffer buffer = new StringBuffer();
while (m.find()) {
m.appendReplacement(buffer,new String(new char[Integer.valueOf(m.group())]).replace("\0", " "));
}
m.appendTail(buffer);
System.out.println(buffer.toString()); // AA DD EE MM
The idea here is to iterate the string, pausing at each digit match. We replace each digit with space replicated the same number of times as the digit.
public static String replaceDigitsWithSpaces(String input) {
String result = "";
int len = input.length(), i =0;
while( i < len) {
if(Character.isLetter(input.charAt(i))) {
result += input.charAt(i);
}else if(Character.isDigit(input.charAt(i))) {
//generate number upto characters
int k = 0, j = i;
String temp = "";
while(j < len) {
if(Character.isDigit(input.charAt(j))) {
temp += input.charAt(j);
j++;
}else {
break;
}
}
k = Integer.parseInt(temp);
while(k != 0) {
result+= " ";
k--;
}
i = j;
continue;
}
i++;
}
return result;
}
input:: "AA23BB1C11C8"<br>
output:: AA BB C C .
StringBuilder is more efficient for concatenation:
public static String spaceIt(String s) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
if (Character.isDigit(c)) {
for (int j = 0; j < Character.digit(c, 10); j++) {
sb.append(' ');
}
} else {
sb.append(c);
}
}
return sb.toString();
}
The input is: i love cake
The output needs to be: Cake Love I
But the actual result is: I Love Cake
What I've got:
import java.util.regex.Pattern;
public class yellow {
static String reverseWords(String str){
Pattern pattern = Pattern.compile("\\s");
String[] temp = pattern.split(str);
String result = "";
for (int i = 0; i < temp.length; i++) {
if (i == temp.length - 1)
result = temp[i] + result;
else
result = " " + temp[i] + result;
}
return result;
}
public static void main(String[] args){
String source = "i love cake";
StringBuffer res = new StringBuffer();
String[] strArr = source.split(" ");
for (String str : strArr) {
char[] stringArray = str.trim().toCharArray();
stringArray[0] = Character.toUpperCase(stringArray[0]);
str = new String(stringArray);
res.append(str).append(" ");
}
System.out.print(res.toString());
}
}
What am I doing wrong?
for (String str : strArr) {
}
This loops forward. What you want is to loop backwards, or to place elements into the string backwards. I recommend you loop backwards and print as you go:
for (int i = strArr.length - 1; i >= 0; i--) {
char[] stringArray = strArr[i].trim().toCharArray();
stringArray[0] = Character.toUpperCase(stringArray[0]);
System.out.println(new String(stringArray));
}
Or, you could use that convenient reverseWords method that you never use anywhere... though looping backwards is faster. Probably.
[EDITED]
Call this for each line with string s, then print a line break (If you have multiple sentences & expect them in their own lines).
void reverseCamel(String s){
String[] ar = s.split("\\s+");
for(int i = ar.length - 1;i>=0;i--){
ar[i][0] = Character.toUpperCase(ar[i][0]);
System.out.print(ar[i] + " ");
}
}
Here is what i did.
public class Main {
public static void main(String[] args) {
reverse("I Love Cake");
}
public static void reverse( String string){
String[] word =string.split(" "); // split by spaces
int i = word.length-1;
while (i>=0){
// System.out.print(word[i].toUpperCase()+" ");//if you want in upper case
System.out.print(word[i]+" ");
i--;
}
}
}
First of all you have to reverse the String.
String[] words = source.split("\\s");
String reversedString = "";
for(int i = words.length -1; i>=0; i--){
reversedString += words[i] + " ";
}
Then, you know that the ASCII code of 'a' character is 97, 'A' is 65. To convert from lower case to capital you substract 32. All capitals are between 65 and 92. All small letters are between 97 and 124.
You want to capitalize only letters at the beginning of a word (preceded by a space or first letter).
String capitalCase = "";
for (int i = 0; i < reversedString.length(); i++) {
char c = reversedString.charAt(i);
if (c >= 97 && c <= 124) {
if (i == 0) c -= 32;
else if ((reversedString.charAt(i - 1) + "").equals(" ")) c -= 32;
}
capitalCase += c;
}
And here you go now System.out.println(capitalCase);
Overall, you will have the following code:
import java.util.Scanner;
public class yellow {
public static void main(String[] args) {
Scanner s = new Scanner(System.in);
System.out.println("Enter a string:");
String source = s.nextLine();
String[] words = source.split("\\s");
String reversedString = "";
for (int i = words.length - 1; i >= 0; i--) {
reversedString += words[i] + " ";
}
String capitalCase = "";
for (int i = 0; i < reversedString.length(); i++) {
char c = reversedString.charAt(i);
if (c >= 97 && c <= 124) {
if (i == 0) c -= 32;
else if ((reversedString.charAt(i - 1) + "").equals(" ")) c -= 32;
}
capitalCase += c;
}
System.out.println(capitalCase);
}
}
Output:
Enter a string:
i love cake
Cake Love I
Java 8 * Apache Commons Lang
public static String reverseWordsInString(String str) {
List<String> words = Pattern.compile("\\s+").splitAsStream(str)
.map(StringUtils::capitalize)
.collect(LinkedList::new, LinkedList::addFirst, (a, b) -> a.addAll(0, b));
return words.stream().collect(Collectors.joining(StringUtils.SPACE));
}
Java 8
public static String reverseWordsInString(String str) {
List<String> words = Pattern.compile("\\s+").splitAsStream(str)
.map(word -> Character.toUpperCase(word.charAt(0)) + word.substring(1).toLowerCase())
.collect(LinkedList::new, LinkedList::addFirst, (a, b) -> a.addAll(0, b));
return words.stream().collect(Collectors.joining(" "));
}
I want to reverse each individual word of a String in Java in different different sitautions (not the entire string, just each individual word).
Example1: if input String is "This is a test" then the output should be "sihT si a tset".
Example2: if input String is "This is a test" then the output should be "sihT si a tset".
[When there is more than one space between some words]
Please also provide algorithm for understanding
What I have tried so far
class reverseAString
{
public static void main(String args[])
{
String str= "Test the product";
String strArr[]= str.split(" ");
for(int i=0;i<=strArr.length-1;i++)
{
for(int j=strArr[i].length()-1; j>=0;j--)
{
System.out.print(strArr[i].charAt(j));
}
System.out.printf(" ");
}
}
}
---------
public String reverseWordByWord(String str){
int strLeng = str.length()-1;
String reverse = "", temp = "";
for(int i = 0; i <= strLeng; i++){
temp += str.charAt(i);
if((str.charAt(i) == ' ') || (i == strLeng)){
for(int j = temp.length()-1; j >= 0; j--){
reverse += temp.charAt(j);
if((j == 0) && (i != strLeng))
reverse += " ";
}
temp = "";
}
}
return reverse;
}
This approach is much more succinct.
class StringRev{
public static void main(String args[]){
String str[] = "Test the product".split(" ");
String finalStr="";
for(int i = str.length-1; i>= 0 ;i--){
finalStr += str[i]+" ";
}
System.out.println(finalStr);
}
}
public static void main(String arg[]) {
System.out.println(reverseWords("This is a test"));
}
// function to reverse each word
public static String reverseWords(String input) {
String result = null;
StringBuffer strBuffer = new StringBuffer();
String split[] = input.split(" ");
for (String temp : split) {
if (temp != " ") {
strBuffer.append(reverse(temp));
strBuffer.append(" ");
} else {
strBuffer.append(" ");
}
}
result = strBuffer.toString();
return result;
}
// function to reverse individual word
public static String reverse(String input) {
StringBuffer strBuffer = new StringBuffer();
char[] charArray = input.toCharArray();
for (int j = charArray.length - 1; j >= 0; j--) {
strBuffer.append(charArray[j]);
}
return strBuffer.toString();
}
Split complete string on basis of space
Then convert each string to character array and reverse
individual word.
It's been a long time since I've touch Java, but here's the algorithm.
String stringToReverse = "This is a Test";
String finalString = "";
Stack word = new Stack;
for(int i = 0; i < stringToReverse.length; i++){
char chr = stringToReverse[i];
if(chr == " " || i == (stringToReverse.length - 1)){
while(word.count > 0){
finalString += word.pop();
}
finalString += chr;
}else{
word.push(chr);
}
}
Given a string in Java, how can I obtain a new string where all adjacent sequences of digits are reversed?
My code:
import static java.lang.System.*;
public class P2
{
public static void main(String[] args)
{
if(args.length < 1)
{
err.printf("Usage: java -ea P2 String [...]\n");
exit(1);
}
String[] norm = new String[args.length];
for(int i = 0; i<norm.length;i++)
{
norm[i] = args[i];
}
}
public String invertDigits(String[] norm)
{
}
}
And as an example, this is what it should do:
Inputs: 1234 abc9876cba a123 312asd a12b34c56d
1234 -> 4321
abc9876cba -> abc6789cba
a123 -> a321
312asd -> 213asd
a12b34c56d -> a21b43c65d
Although the question is heavily downvoted, the proposed problem seems clear now. I chose to solve it using a regular expression match in a recursive function.
private static String reverseDigits(String s) {
// the pattern will match a sequence of 1 or more digits
Matcher matcher = Pattern.compile("\\d+").matcher(s);
// fetch the position of the next sequence of digits
if (!matcher.find()) {
return s; // no more digits
}
// keep everything before the number
String pre = s.substring(0, matcher.start());
// take the number and reverse it
String number = matcher.group();
number = new StringBuilder(number).reverse().toString();
// continue with the rest of the string, then concat!
return pre + number + reverseDigits(s.substring(matcher.end()));
}
And here's the iterative approach.
private static String reverseDigits(String s) {
//if (s.isEmpty()) return s;
String res = "";
int base = 0;
Matcher matcher = Pattern.compile("\\d+").matcher(s);
while (!matcher.hitEnd()) {
if (!matcher.find()) {
return res + s.substring(base);
}
String pre = s.substring(base, matcher.start());
base = matcher.end();
String number = matcher.group();
number = new StringBuilder(number).reverse().toString();
res += pre + number;
}
return res;
}
String str = "1234";
//indexes
int i = 0, j = str.length()-1;
// find digits (if any)
while (!Character.isDigit(str.charAt(i)) && i < str.length()) {
i++;
}
while (!Character.isDigit(str.charAt(j)) && j >= 0) {
j--;
}
// while we havent searched all the digits
while (i < j) {
// switch digits
str = str.substring(0, i) + str.charAt(j) + str.substring(i + 1, j) + str.charAt(i) + str.substring(j + 1);
i++;
j--;
// find the next digits
while (!Character.isDigit(str.charAt(i)) && i < str.length()) {
i++;
}
while (!Character.isDigit(str.charAt(j)) && j >= 0) {
j--;
}
}
System.out.println(str);
Another dynamic approach without using regex classes:
public static String reverseOnlyNumbers(String s) {
StringBuilder digits = new StringBuilder();
StringBuilder result = new StringBuilder();
boolean start = false;
for (int i = 0; i < s.length(); i++) {
Character c = s.charAt(i);
if (Character.isDigit(c)) {
start = true;
digits.append(c);
}else {
start = false;
if (digits.length() > 0) {
result.append(digits.reverse().toString());
digits = new StringBuilder();
}
result.append(c);
}
}
return start ? result.append(digits.reverse()).toString() : result.toString();
}