I have the following values:
int a=1;
int b=0;
int c=2;
int d=2;
int e=1;
How do i concatenate these values so that i end up with a String that is 10221;
please note that multiplying a by 10000, b by 1000.....and e by 1 will not working since b=0 and therefore i will lose it when i add the values up.
The easiest (but somewhat dirty) way:
String result = "" + a + b + c + d + e
Edit: I don't recommend this and agree with Jon's comment. Adding those extra empty strings is probably the best compromise between shortness and clarity.
Michael Borgwardt's solution is the best for 5 digits, but if you have variable number of digits, you can use something like this:
public static String concatenateDigits(int... digits) {
StringBuilder sb = new StringBuilder(digits.length);
for (int digit : digits) {
sb.append(digit);
}
return sb.toString();
}
This worked for me.
int i = 14;
int j = 26;
int k = Integer.valueOf(String.valueOf(i) + String.valueOf(j));
System.out.println(k);
It turned out as 1426
just to not forget the format method
String s = String.format("%s%s%s%s%s", a, b, c, d, e);
(%1.1s%1.1s%1.1s%1.1s%1.1s if you only want the first digit of each number...)
Actually,
int result = a * 10000 + b * 1000 + c * 100 + d * 10 + e;
String s = Integer.toString(result);
will work.
Note: this will only work when a is greater than 0 and all of b, c, d and e are in [0, 9]. For example, if b is 15, Michael's method will get you the result you probably want.
How about not using strings at all...
This should work for any number of digits...
int[] nums = {1, 0, 2, 2, 1};
int retval = 0;
for (int digit : nums)
{
retval *= 10;
retval += digit;
}
System.out.println("Return value is: " + retval);
StringBuffer sb = new StringBuffer();
sb.append(a).append(b).append(c)...
Keeping the values as an int is preferred thou, as the other answers show you.
If you multiply b by 1000, you will not lose any of the values. See below for the math.
10000
0
200
20
1
=====
10221
Others have pointed out that multiplying b by 1000 shouldn't cause a problem - but if a were zero, you'd end up losing it. (You'd get a 4 digit string instead of 5.)
Here's an alternative (general purpose) approach - which assumes that all the values are in the range 0-9. (You should quite possibly put in some code to throw an exception if that turns out not to be true, but I've left it out here for simplicity.)
public static String concatenateDigits(int... digits)
{
char[] chars = new char[digits.length];
for (int i = 0; i < digits.length; i++)
{
chars[i] = (char)(digits[i] + '0');
}
return new String(chars);
}
In this case you'd call it with:
String result = concatenateDigits(a, b, c, d, e);
For fun... how NOT to do it ;-)
String s = Arrays.asList(a,b,c,d,e).toString().replaceAll("[\\[\\], ]", "");
Not that anyone would really think of doing it this way in this case - but this illustrates why it's important to give access to certain object members, otherwise API users end up parsing the string representation of your object, and then you're stuck not being able to modify it, or risk breaking their code if you do.
Using Java 8 and higher, you can use the StringJoiner, a very clean and more flexible way (especially if you have a list as input instead of known set of variables a-e):
int a = 1;
int b = 0;
int c = 2;
int d = 2;
int e = 1;
List<Integer> values = Arrays.asList(a, b, c, d, e);
String result = values.stream().map(i -> i.toString()).collect(Collectors.joining());
System.out.println(result);
If you need a separator use:
String result = values.stream().map(i -> i.toString()).collect(Collectors.joining(","));
To get the following result:
1,0,2,2,1
Edit: as LuCio commented, the following code is shorter:
Stream.of(a, b, c, d, e).map(Object::toString).collect(Collectors.joining());
int number =0;
int[] tab = {your numbers}.
for(int i=0; i<tab.length; i++){
number*=10;
number+=tab[i];
}
And you have your concatenated number.
I would suggest converting them to Strings.
StringBuilder concatenated = new StringBuilder();
concatenated.append(a);
concatenated.append(b);
/// etc...
concatenated.append(e);
Then converting back to an Integer:
Integer.valueOf(concatenated.toString());
Use StringBuilder
StringBuilder sb = new StringBuilder(String.valueOf(a));
sb.append(String.valueOf(b));
sb.append(String.valueOf(c));
sb.append(String.valueOf(d));
sb.append(String.valueOf(e));
System.out.print(sb.toString());
People were fretting over what happens when a == 0. Easy fix for that...have a digit before it. :)
int sum = 100000 + a*10000 + b*1000 + c*100 + d*10 + e;
System.out.println(String.valueOf(sum).substring(1));
Biggest drawback: it creates two strings. If that's a big deal, String.format could help.
int sum = a*10000 + b*1000 + c*100 + d*10 + e;
System.out.println(String.format("%05d", sum));
You can Use
String x = a+"" +b +""+ c+""+d+""+ e;
int result = Integer.parseInt(x);
Assuming you start with variables:
int i=12;
int j=12;
This will give output 1212:
System.out.print(i+""+j);
And this will give output 24:
System.out.print(i+j);
Best solutions are already discussed.
For the heck of it, you could do this as well:
Given that you are always dealing with 5 digits,
(new java.util.Formatter().format("%d%d%d%d%d", a,b,c,d,e)).toString()
I am not claiming this is the best way; just adding an alternate way to look at similar situations. :)
NOTE: when you try to use + operator on (string + int) it converts int into strings and
concatnates them !
so you need to convert only one int to string
public class scratch {
public static void main(String[] args){
int a=1;
int b=0;
int c=2;
int d=2;
int e=1;
System.out.println( String.valueOf(a)+b+c+d+e) ;
}
//Here is the simplest way
public class ConcatInteger{
public static void main(String[] args) {
int [] list1={1,2,3};
int [] list2={1,9,6};
String stNum1="";
String stNum2="";
for(int i=0 ; i<3 ;i++){
stNum1=stNum1+Integer.toString(list2[i]); //Concat done with string
}
for(int i=0 ; i<3 ;i++){
stNum2=stNum2+Integer.toString(list1[i]);
}
int sum= Integer.parseInt(stNum1)+Integer.parseInt(stNum2); // Converting string to int
System.out.println(sum);
}
}
Couldn't you just make the numbers strings, concatenate them, and convert the strings to an integer value?
public class joining {
public static void main(String[] args) {
int a=1;
int b=0;
int c=2;
int d=2;
int e=1;
String j = Long.toString(a);
String k = Long.toString(b);
String l = Long.toString(c);
String m = Long.toString(d);
String n = Long.toString(e);
/* String s1=Long.toString(a); // converting long to String
String s2=Long.toString(b);
String s3=s2+s1;
long c=Long.valueOf(s3).longValue(); // converting String to long
*/
System.out.println(j+k+l+m+n);
}
}
Related
I have an assignment in which we are instructed to create a method which takes a string, scrambles the content of the string, and then returns the scrambled string (ie "Hello" returns "elloH"). However, we are only allowed to do this via loops and basic string functions (no arrays can be used).
My Teacher has left the following suggestion for us:
The best way to shuffle is to generate 2 random numbers (index number) and swap the numbers(the content, not the index) based on the random index numbers.
Continue to do it for 100 times, they are shuffled and all characters remain the same but in different positions
How would this nessasarily be done? For reference here is my try at the solution, however it does not work and I'm not sure where to go from here:
public void shuffle(String s1) {
int i1 = 0;
int i2 = 0;
String s2 = "";
for(int a2 = 0; a2 < s1.length(); a2++) {
char c1 = s1.charAt(i1);
s2 += c1;
for(int a1 = 0; a1 < 100; a1++) {
double d1 = Math.random();
d1 *= (s1.length()-1);
i1 = (int) d1;
}
}
System.out.println(s2);
}
The problem with your code is that you don't swap characters in the String but rather select randomly across the String which causes some characters to be used many times and some not at all.
I would do something like this using StringBuilder that is suitable for String manipulations as long as the String itself is immutable (calling any method from it does not change the former object but returns a new one).
// it's a good practice to delcare formal parameters in a method as final
public void shuffle(final String string) {
// store the string length to a variable for sake of comfort
final int length = string.length();
// use mutable StringBuilder for easy String manipulations
final StringBuilder stringBuilder = new StringBuilder(string);
// initialize the Random object generator once and use many times
// as you don't want to initialize with each loop and throw it away
final Random random = new Random();
// define the number of iterations
// to repeat as many times as the string is long is more than enough
for (int i=0; i<length; i++) {
// pick two random indices to be swapped
final int firstIndex = random.nextInt(length);
final int secondIndex = random.nextInt(length);
// remember the swapped characters
// otherwise it would end up in a mess and duplicated characters
final char firstChar = stringBuilder.charAt(firstIndex);
final char secondChar = stringBuilder.charAt(secondIndex);
// perform the swap: basically set the characters to their positions
stringBuilder.setCharAt(firstIndex, secondChar);
stringBuilder.setCharAt(secondIndex, firstChar);
}
// and see the result
System.out.println(stringBuilder);
}
Run three times (it looks nicely swapped and the characters remain unchanged):
WoodeHl rl!l
Wer lldooHl!
HW! llrloeod
Hi here is the updated code with your requirement I tried not using the concepts out of string manipulation the swap is not using StringBuilder (that would be the best way to do that but if not needed here as a custom logic to do so)
and also used Math.random() to generate the random number if you want to see all 100 iterations just print the s1 in the for loop.
static String swap(String str, int i, int j) {
// if both indexes are the same change nothing
if (i == j)
return str;
// if the second index is last then there will be no substring from j+1 to last;
if (j == str.length() - 1)
return str.substring(0, i) + str.charAt(j) + str.substring(1 + i, j) + str.charAt(i);
return str.substring(0, i) + str.charAt(j) + str.substring(1 + i, j) + str.charAt(i)
+ str.substring(j + 1, str.length());
}
public static void shuffle(String s1) {
// iterate the same logic 100 times
for (int a1 = 0; a1 < 100; a1++) {
// generate 2 random numbers in the range of the length of string
int randomNumber1 = (int) (Math.random() * s1.length());
int randomNumber2 = (int) (Math.random() * s1.length());
// setting the lower random number to randomnumber1 (it is swapping two number without temp)
if (randomNumber1 > randomNumber2) {
randomNumber1 = randomNumber1 + randomNumber2;
randomNumber2 = randomNumber1 - randomNumber2;
randomNumber1 -= randomNumber2;
}
// calling the swap method to swap the chars in string.
s1 = swap(s1, randomNumber1, randomNumber2);
}
System.out.println(s1);
}
Since you cannot use arrays, try using StringBuilder.
private String shuffleUtil(String s) {
final StringBuilder result = new StringBuilder(s);
for (int rep = 1; rep <= 100; rep++) {
final int randomOne = ThreadLocalRandom.current().nextInt(0, s.length());
final int randomTwo = ThreadLocalRandom.current().nextInt(0, s.length());
final char c = result.charAt(randomOne);
result.setCharAt(randomOne, result.charAt(randomTwo));
result.setCharAt(randomTwo, c);
}
return result.toString();
}
public void shuffle(String s) {
final String result = shuffleUtil(s);
System.out.println(s);
}
I want to exhaustively test a String matching algorithm, named myAlgo(Char[] a, Char[] b)
The exhaustive test includes a no. of different char letters, alplhabet " l ", in an "n" long array. The test then computes all combinations, while comparing it with all combinations of another array with similar properties (Like truth tables),e.g.
I have not been able to either compute something that would generate every combination of the array of size n and alphabet l, niether have I been able to make code that is able to combine the computation into iterative testcases (test all the combinations of the two arrays compared), though with code that would be able to generate the combinations, making a nested for-loop should do the required testing.
My goal is to break my algorithm by making it compute something it should not compute.
Test(char[] l, int n)
l = [a;b] //a case could be
n = 2 //a case could be
myAlgo([a;a],[a;a]); //loops over my algorithm in the following way
myAlgo([a;b],[a;a]);
myAlgo([b;a],[a;a]);
myAlgo([b;b],[a;a]);
myAlgo([a;a],[a;b]);
myAlgo([a;b],[a;b]);
myAlgo([b;a],[a;b]);
myAlgo([b;b],[a;b]);
myAlgo([a;a],[b;a]);
myAlgo([a;b],[b;a]);
...
myAlgo([b;b],[b;b]);
My own solution (only works for a finite set of "l") and also starts printing wierd outputs on later iterations.
public class Test {
//aux function to format chars
public static String concatChar(char [] c){
String s = "";
for(char cc : c){
s += cc;
}
return s;
}
public static void main(String[] args) {
String ss1 = "AA"; //TestCases, n = 2
String ss2 = "AA";
char[] test1 = ss1.toCharArray();
char[] test2 = ss2.toCharArray();
Fordi fordi = new Fordi(); //my algorithm
TestGenerator tGen = new TestGenerator(); //my testGenerator
for(int i=0; i<Math.pow(4.0, 2.0);i++){ //to test all different cases
for(int j=0; j<Math.pow(4.0, 2.0);j++){
int k = fordi.calculate(test1, test2); //my algorithm
String mys1 = concatChar(test1); //to print result
String mys2 = concatChar(test2); //to print result
System.out.println(mys1 + " - " + mys2);
System.out.println(k);
test2 = tGen.countArray(test2); //"flip" one number
}
test2 = ss1.toCharArray();
test1 = tGen.countArray(test1); //"flip"
}
}
}
My arrayflipper code:
public char[] countArray(char[] a){
int i=0;
while(i<a.length){
switch (a[i]){
case 'A':
a[i]='B';
clearBottom(a,i);
return a;
case 'B':
a[i]='C';
clearBottom(a,i);
return a;
case 'C':
a[i]='D';
clearBottom(a,i);
return a;
case 'D':
i++;
break;
default:
System.out.println("Something went terribly wrong!");
}
}
return a;
}
public char[] clearBottom(char [] a, int i){
while(i >0){
i--;
a[i] = 'A';
}
return a;
}
As I understand it, your goal is to create all n-character long strings (stored individually as elements in an array) consisting of letters in the L letter alphabet?
One way to accomplish this is to order your letters (A=0, B=1, C=2, etc). Then you can, from a starting string of AAA...AAA (n-characters long) just keep adding 1. Essentially you implement an addition algorithm. Adding 1 would turn an A=0 into a B=1. For example, n=3 and L=3:
start: AAA (0,0,0).
Adding 1 becomes AAB (0,0,1)
Adding 1 again become AAC (0, 0, 2)
Adding 1 again (since we are out of letters, now we carry a bit over) ABA (0, 1, 0).
You can boil the process down to looking for the right-most number that is not maxed out and add 1 to it (then all digits to the right of that digit go back to zero). So in the string ABCCC, the B digit is the right-most not maxed out digit, it goes up by 1 and becomes a C, then all the maxed out digits to the right go back to 0 (A) leaving ACAAA as the next string.
Your algorithm just repeatedly adds 1 until all the elements in the string are maxed out.
Instead of using a switch statement, I recommend putting every character you want to test (A, B, C, D) into an array, and then using the XOR operation to calculate the index of each character from the iteration number in a manner similar to the following:
char[] l = new char[]{'A','B','C','D'};
int n = 2;
char[] test1 = new char[n];
char[] test2 = new char[n];
int max = (int)Math.pow(l.length, n);
for (int i = 0; i < max; i++) {
for (int k = 0; k < n; k++) {
test2[k] = l[(i % (int)Math.pow(l.length, k + 1)) / (int)Math.pow(l.length, k)];
}
for (int j = 0; j < max; j++) {
for (int k = 0; k < n; k++) {
test1[k] = l[(j % (int)Math.pow(l.length, k + 1)) / (int)Math.pow(l.length, k)];
}
int k = fordi.calculate(test1, test2);
System.out.println(new String(test1) + "-" + new String(test2));
System.out.println(k);
}
}
You can add more characters to l as well as increase n and it should still work. Of course, this can be further optimized, but you should get the idea. Hope this answer helps!
I have numeric input (11 digits), and I need to perform some operations on each digit (example: multiply 1st by 5, 2nd by 3, etc.). How can I do so in Java? Is there a simple way to access single letter / digit? Is there another way to do it?
If you don't want to convert the number to a string, then there is a simple trick.
digit = number % 10
will give you the right most digit.
number = number / 10
Will remove the right most digit from the number.
So you can run in a loop until the number reaches 0.
while(0 < number)
{
int digit = number % 10;
number = number / 10;
// do here an operation on the digits
}
You can use a for loop to help you count. For example
for(int index = 0; 0 < number; ++index, number /= 10)
{
int digit = number % 10;
// do an operation on the number according to the 'index' variable
}
Here is a similar StackOverFlow question on a similar question
Well there are many ways you can do it like :
int a = 12345;
int b;
while(a>0)
{
b = a%10;
System.out.print(b + " ");
a = a/10;
}
Here it gives you the digits in reverse order like you will get b=5 then b=4....
You can just manipulate them
Other way
int d = 12345;
String str = String.valueOf(d);
for(int i=0;i<str.length();i++)
{
char c = str.charAt(i);
System.out.print(Character.getNumericValue(c) * 10 + " ");
}
Or
char c[] = str.toCharArray();
for(Character ch : c)
{
System.out.print(Character.getNumericValue(ch) * 2 + " ");
}
You can use .charAt() to get a character from a string. Then using Character.getNumericValue() you can convert the character to an integer.
Like this:
String string = "1434347633";
int digit1 = Character.getNumericValue(string.charAt(1));
Convert that number input to String data type so that you can interpret it as a String.
int numbers = 1122334455; // integer won't be able to save this much data,
// just for example ok,
String numberString = numbers.toString();
foreach (char number in numberString) {
// do work on each of the single character in the string.
}
You should work them out, depending on the some condition.
If you want to access the digits by index without converting to a string, you can use these two functions length and digitAt:
public class DigitAt {
public static int length(long v) {
return (int) Math.ceil(Math.log10(v));
}
public static int digitAt(long v, int digit) {
return (int) ((v / (long) Math.pow(10, length(v) - digit - 1)) % 10);
}
public static void main(String[] args) {
System.out.println("Digits: " + length(1234567));
System.out.println(digitAt(1234567, 0));
System.out.println(digitAt(1234567, 1));
System.out.println(digitAt(1234567, 6));
}
}
public String stringAfterOperations(String digits) {
ArrayList<Integer> z = new ArrayList<Integer>();
for(Character c: digits.toCharArray()) {
z.add(Character.getNumericValue(c));
}
//TODO Set your own operations inside this "for"
for(int i=0; i<z.size(); i++){
if(i == 1){
z.set(i, z.get(i)*4);
}
else if(i == 7){
z.set(i, z.get(i)/3);
}
else {
z.set(i, z.get(i)+2);
}
}
String newString = "";
for(Integer i: z){
newString += i;
}
return newString;
}
So if I have an inputted integer:
int num_1 = 128
How would I be able to parse through the number and obtain a 1, 2 and 8, and assign them to different variables?
Thanks!
the inefficient way to do this would be to convert the integer to a string and iterate on the string characters.
the more efficient way would be something like:
int n = 128;
while (n > 0) {
int d = n / 10;
int k = n - d * 10;
n = d;
System.out.println(k);
}
The answer that Thilo wrote is good but incomplete, you start by doing:
char[] digitsAsChars = String.valueOf(num_1).toCharArray();
and then:
int[] digits = new int[charNums.length];
for(int i=0; i<charNums.length; i++){
digits[i] = charNums[i]-48;//convert char to int
}
now digits holds the digits of the number as an int array
try
while (num_1> 0){
int digit = num_1%10;
num_1 = num_1/10;
System.out.println(digit);
}
int num = 128;
String number = String.valueOf(num);
for(int i = 0; i < number.length(); i++) {
int j = Character.digit(number.charAt(i), 10);
System.out.println("digit: " + j);
}
Output:
digit: 1
digit: 2
digit: 8
Turn it into a String and go character by character for the digits:
char[] digits = String.valueOf(num_1).toCharArray();
Here's one way:
String digits = Integer.toString(num_1);
int digit1 = Character.digit(digits.charAt(0), 10);
int digit2 = Character.digit(digits.charAt(1), 10);
int digit3 = Character.digit(digits.charAt(2), 10);
Of course, if the integer has more than three digits, using a loop would be more practical:
String sDigits = Integer.toString(num_1);
char[] cDigits = sDigits.toCharArray();
int[] digits = new int[cDigits.length];
for (int i = 0; i < cDigits.length; i++)
digits[i] = Character.digit(cDigits[i], 10);
With the above code in place, it's easy to extract the digits from the array:
int digit1 = digits[0];
int digit2 = digits[1];
int digit3 = digits[2];
Collect all the digits in the Array and use futher
import java.lang.Integer;
import java.lang.String;
import java.util.ArrayList;
import java.util.List;
import java.util.Arrays;
public class Test
{
public static void main(String[] args) {
Integer num = 12345;
Integer[] digits = getDigits(num.toString());
System.out.println(Arrays.toString(digits));
}
public static Integer[] getDigits(String number) {
List<Integer> digits = new ArrayList<Integer>();
for(int i = 0; i < number.length(); i++) {
int j = Character.digit(number.charAt(i), 10);
digits.add(j);
}
return digits.toArray(new Integer[]{});
}
}
Output should be
[1, 2, 3, 4, 5]
Here is a purely mathematical way of doing so:
// Returns digit at pos
static int digitAt(int input, int pos){
int i =(int) (input%(Math.pow(10, pos)));
int j = (int) (i/Math.pow(10, pos-1));
return Math.abs(j); // abs handles negative input
}
For example if input = 1234 and pos = 2, then i is 34. We divide the 34 by 10 and round off to get a 3.
Not that pretty, but works!
String str = Integer.toString(num_1);
You can obtain 1,2,8 from this str
This code returns the nibble at the given index. If you want to get all digits, you can call this method with all indices of your number. It does not work on the hexadecimal representation of a number but on the decimal one.
public static int getNibble(int number, int nibbleIndex)
{
int nibble = 0;
while (nibbleIndex >= 0)
{
int division = number / 10;
nibble = number - division * 10;
number = division;
nibbleIndex--;
}
return nibble;
}
Now if you are trying to single out numbers in a string among letters then this should take care of that.
String string = "Th1s 1s n0t a number";
int newNum = Integer.parseInt(string.replaceAll("[\\D]", ""));
return newNum;
This should return 110
Also, here is a link to a stack discussion that I found really helpful.
Get int from String, also containing letters, in Java
If you don't appreciate the idea of String conversion and want to iterate using normal order, try this:
int n = 123456789;
int digits = (int) Math.log10(n);
for (int i = (int) Math.pow(10, digits); i > 0; i /= 10) {
System.out.println(n / i);
n %= i;
}
Output would be
1
2
3
4
5
6
7
8
9
To know where the digits are coming from I'd go:
return (x/10/10) + (x%10) + (x/10)%10;
I think you can use this solution :
int getDigit(int num,int location){
return BigDecimal.valueOf(num/Math.pow(10,position)).intValue() %10;
}
in this solution what will happen is the following you are sending a number due to usage of Math that returns a double we need to convet it again to integer we use the BigDecimal.
the main idea or logic is the Math.pow with the position it returns the prefix of number and then the module chops the other end.
you can check it with the following Sample:
System.out.println(getDigit(123456,1));
System.out.println(getDigit(123456,2));
System.out.println(getDigit(123456,3));
System.out.println(getDigit(123456,4));
System.out.println(getDigit(123456,5));
System.out.println(getDigit(123456,10) );
Enjoy
Java 8 Solution
String.valueOf(n).chars().forEach(i -> System.out.println((char) i))
where n=the integer
What is the most efficient way to reverse a string in Java? Should I use some sort of xor operator? The easy way would be to put all the chars in a stack and put them back into a string again but I doubt that's a very efficient way to do it.
And please do not tell me to use some built in function in Java. I am interested in learning how to do it not to use an efficient function but not knowing why it's efficient or how it's built up.
You say you want to know the most efficient way and you don't want to know some standard built-in way of doing this. Then I say to you: RTSL (read the source, luke):
Check out the source code for AbstractStringBuilder#reverse, which gets called by StringBuilder#reverse. I bet it does some stuff that you would not have considered for a robust reverse operation.
The following does not deal with UTF-16 surrogate pairs.
public static String reverse(String orig)
{
char[] s = orig.toCharArray();
int n = s.length;
int halfLength = n / 2;
for (int i=0; i<halfLength; i++)
{
char temp = s[i];
s[i] = s[n-1-i];
s[n-1-i] = temp;
}
return new String(s);
}
You said you don't want to do it the easy way, but for those Googling you should use StringBuilder.reverse:
String reversed = new StringBuilder(s).reverse().toString();
If you need to implement it yourself, then iterate over the characters in reverse order and append them to a StringBuilder. You have to be careful if there are (or can be) surrogate pairs, as these should not be reversed. The method shown above does this for you automatically, which is why you should use it if possible.
An old post & question, however still did not see answers pertaining to recursion. Recursive method reverse the given string s, without relaying on inbuilt jdk functions
public static String reverse(String s) {
if (s.length() <= 1) {
return s;
}
return reverse(s.substring(1)) + s.charAt(0);
}
`
The fastest way would be to use the reverse() method on the StringBuilder or StringBuffer classes :)
If you want to implement it yourself, you can get the character array, allocate a second character array and move the chars, in pseudo code this would be like:
String reverse(String str) {
char[] c = str.getCharArray
char[] r = new char[c.length];
int end = c.length - 1
for (int n = 0; n <= end; n++) {
r[n] = c[end - n];
}
return new String(r);
}
You could also run half the array length and swap the chars, the checks involved slow things down probably.
I'm not really sure by what you mean when you say you need an efficient algorithm.
The ways of reversing a string that I can think of are (they are all already mentioned in other answers):
Use a stack (your idea).
Create a new reversed String by adding characters one by one in reverse order from the original String to a blank String/StringBuilder/char[].
Exchange all characters in the first half of the String with its corresponding position in the last half (i.e. the ith character gets swapped with the (length-i-1)th character).
The thing is that all of them have the same runtime complexity: O(N). Thus it cannot really be argued that any one is any significantly better than the others for very large values of N (i.e. very large strings).
The third method does have one thing going for it, the other two require O(N) extra space (for the stack or the new String), while it can perform swaps in place. But Strings are immutable in Java so you need to perform swaps on a newly created StringBuilder/char[] anyway and thus end up needing O(N) extra space.
public class ReverseInPlace {
static char[] str=null;
public static void main(String s[]) {
if(s.length==0)
System.exit(-1);
str=s[0].toCharArray();
int begin=0;
int end=str.length-1;
System.out.print("Original string=");
for(int i=0; i<str.length; i++){
System.out.print(str[i]);
}
while(begin<end){
str[begin]= (char) (str[begin]^str[end]);
str[end]= (char) (str[begin]^str[end]);
str[begin]= (char) (str[end]^str[begin]);
begin++;
end--;
}
System.out.print("\n" + "Reversed string=");
for(int i=0; i<str.length; i++){
System.out.print(str[i]);
}
}
}
I think that if you REALLY don't have performance problem you should just go with the most readable solution which is:
StringUtils.reverse("Hello World");
private static String reverse(String str) {
int i = 0;
int j = str.length()-1;
char []c = str.toCharArray();
while(i <= j){
char t = str.charAt(i);
c[i] = str.charAt(j);
c[j]=t;
i++;
j--;
}
return new String(c);
}
If you do not want to use any built in function, you need to go back with the string to its component parts: an array of chars.
Now the question becomes what is the most efficient way to reverse an array? The answer to this question in practice also depends upon memory usage (for very large strings), but in theory efficiency in these cases is measured in array accesses.
The easiest way is to create a new array and fill it with the values you encounter while reverse iterating over the original array, and returning the new array. (Although with a temporary variable you could also do this without an additional array, as in Simon Nickersons answer).
In this way you access each element exactly once for an array with n elements. Thus giving an efficiency of O(n).
I would simply do it this way without a use of any single util function. Just the String class is sufficient.
public class MyStringUtil {
public static void main(String[] args) {
String reversedString = reverse("StringToReverse");
System.out.println("Reversed String : " + reversedString);
}
/**
* Reverses the given string and returns reversed string
*
* #param s Input String
* #returns reversed string
*/
private static String reverse(String s) {
char[] charArray = s.toCharArray(); // Returns the String's internal character array copy
int j = charArray.length - 1;
for (int i = 0; charArray.length > 0 && i < j; i++, j--) {
char ch = charArray[i];
charArray[i] = charArray[j];
charArray[j] = ch;
}
return charArray.toString();
}
}
Check it. Cheers!!
Using String:
String abc = "abcd";
int a= abc.length();
String reverse="";
for (int i=a-1;i>=0 ;i--)
{
reverse= reverse + abc.charAt(i);
}
System.out.println("Reverse of String abcd using invert array is :"+reverse);
Using StringBuilder:
String abc = "abcd";
int a= abc.length();
StringBuilder sb1 = new StringBuilder();
for (int i=a-1;i>=0 ;i--)
{
sb1= sb1.append(abc.charAt(i));
}
System.out.println("Reverse of String abcd using StringBuilder is :"+sb1);
One variant can be, swapping the elements.
int n = length - 1;
char []strArray = str.toCharArray();
for (int j = 0; j < n; j++) {
char temp = strArray[j];
char temp2 = strArray[n];
strArray[j] = temp2;
strArray[n] = temp;
n--;
}
public static void main(String[] args){
String string ="abcdefghijklmnopqrstuvwxyz";
StringBuilder sb = new StringBuilder(string);
sb.reverse();
System.out.println(sb);
}
public static String Reverse(String word){
String temp = "";
char[] arr = word.toCharArray();
for(int i = arr.length-1;i>=0;i--){
temp = temp+arr[i];
}
return temp;
}
char* rev(char* str)
{
int end= strlen(str)-1;
int start = 0;
while( start<end )
{
str[start] ^= str[end];
str[end] ^= str[start];
str[start]^= str[end];
++start;
--end;
}
return str;
}
=========================
Wondering how it works?
First operation:
x1 = x1 XOR x2
x1: 1 0 0
x2: 1 1 1
New x1: 0 1 1
Second operation
x2 = x2 XOR x1
x1: 0 1 1
x2: 1 1 1
New x2: 1 0 0
//Notice that X2 has become X1 now
Third operation:
x1 = x1 XOR x2
x1: 0 1 1
x2: 1 0 0
New x1: 1 1 1
//Notice that X1 became X2
public static string getReverse(string str)
{
char[] ch = str.ToCharArray();
string reverse = "";
for (int i = str.Length - 1; i > -1; i--)
{
reverse += ch[i];
}
return reverse;
}
//using in-built method reverse of Array
public static string getReverseUsingBulidingFunction(string str)
{
char[] s = str.ToCharArray();
Array.Reverse(s);
return new string(s);
}
public static void Main(string[] args)
{
string str = "123";
Console.WriteLine("The reverse string of '{0}' is: {1}",str,getReverse(str));
Console.WriteLine("The reverse string of '{0}' is: {1}", str, getReverseUsingBulidingFunction(str));
Console.ReadLine();
}
Using multiple threads to swap the elements:
final char[] strArray = str.toCharArray();
IntStream.range(0, str.length() / 2).parallel().forEach(e -> {
final char tmp = strArray[e];
strArray[e] = strArray[str.length() - e - 1];
strArray[str.length() - e - 1] = tmp;
});
return new String(strArray);
Of course this is the most efficient way:
String reversed = new StringBuilder(str).reverse().toString();
But if you don't like using that then I recommend this instead:
public String reverseString(String str)
{
String output = "";
int len = str.length();
for(int k = 1; k <= str.length(); k++, len--)
{
output += str.substring(len-1,len);
}
return output;
}
static String ReverseString(String input) {
var len = input.Length - 1;
int i = 0;
char[] revString = new char[len+1];
while (len >= 0) {
revString[i] = input[len];
len--;
i++;
}
return new string(revString);
}
why can't we stick with the simplest loop and revere with character read and keep adding to the char array, I have come across with a whiteboard interview, where interviewer set restrictions on not to use StringBuilder and inbuilt functions.
This is the optimal way to reverse a string with O(log n) complexity.
public char[] optimisedArrayReverse(char[] chars) {
char[] reversedChars = chars;
int length = chars.length;
int center = (length / 2) - 1;
int reversedIndex = chars.length - 1;
if (center < 0) {
return chars;
}
for (int index = 0; index <= center; index++) {
//Swap values
char temp = reversedChars[index];
reversedChars[index] = chars[reversedIndex];
reversedChars[reversedIndex] = temp;
reversedIndex --;
}
return reversedChars;
}
public static String reverseString(String str)
{
StringBuilder sb = new StringBuilder();
for (int i = str.length() - 1; i >= 0; i--)
{
sb.append(str[i]);
}
return sb.toString();
}