Related
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
I have "Hello World" kept in a String variable named hi.
I need to print it, but reversed.
How can I do this? I understand there is some kind of a function already built-in into Java that does that.
Related: Reverse each individual word of “Hello World” string with Java
You can use this:
new StringBuilder(hi).reverse().toString()
StringBuilder was added in Java 5. For versions prior to Java 5, the StringBuffer class can be used instead — it has the same API.
For Online Judges problems that does not allow StringBuilder or StringBuffer, you can do it in place using char[] as following:
public static String reverse(String input){
char[] in = input.toCharArray();
int begin=0;
int end=in.length-1;
char temp;
while(end>begin){
temp = in[begin];
in[begin]=in[end];
in[end] = temp;
end--;
begin++;
}
return new String(in);
}
public static String reverseIt(String source) {
int i, len = source.length();
StringBuilder dest = new StringBuilder(len);
for (i = (len - 1); i >= 0; i--){
dest.append(source.charAt(i));
}
return dest.toString();
}
http://www.java2s.com/Code/Java/Language-Basics/ReverseStringTest.htm
String string="whatever";
String reverse = new StringBuffer(string).reverse().toString();
System.out.println(reverse);
I am doing this by using the following two ways:
Reverse string by CHARACTERS:
public static void main(String[] args) {
// Using traditional approach
String result="";
for(int i=string.length()-1; i>=0; i--) {
result = result + string.charAt(i);
}
System.out.println(result);
// Using StringBuffer class
StringBuffer buffer = new StringBuffer(string);
System.out.println(buffer.reverse());
}
Reverse string by WORDS:
public static void reverseStringByWords(String string) {
StringBuilder stringBuilder = new StringBuilder();
String[] words = string.split(" ");
for (int j = words.length-1; j >= 0; j--) {
stringBuilder.append(words[j]).append(' ');
}
System.out.println("Reverse words: " + stringBuilder);
}
Take a look at the Java 6 API under StringBuffer
String s = "sample";
String result = new StringBuffer(s).reverse().toString();
Here is an example using recursion:
public void reverseString() {
String alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
String reverseAlphabet = reverse(alphabet, alphabet.length()-1);
}
String reverse(String stringToReverse, int index){
if(index == 0){
return stringToReverse.charAt(0) + "";
}
char letter = stringToReverse.charAt(index);
return letter + reverse(stringToReverse, index-1);
}
Here is a low level solution:
import java.util.Scanner;
public class class1 {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
String inpStr = in.nextLine();
System.out.println("Original String :" + inpStr);
char temp;
char[] arr = inpStr.toCharArray();
int len = arr.length;
for(int i=0; i<(inpStr.length())/2; i++,len--){
temp = arr[i];
arr[i] = arr[len-1];
arr[len-1] = temp;
}
System.out.println("Reverse String :" + String.valueOf(arr));
}
}
I tried, just for fun, by using a Stack. Here my code:
public String reverseString(String s) {
Stack<Character> stack = new Stack<>();
StringBuilder sb = new StringBuilder();
for (int i = 0; i < s.length(); i++) {
stack.push(s.charAt(i));
}
while (!stack.empty()) {
sb.append(stack.pop());
}
return sb.toString();
}
Since the below method (using XOR) to reverse a string is not listed, I am attaching this method to reverse a string.
The Algorithm is based on :
1.(A XOR B) XOR B = A
2.(A XOR B) XOR A = B
Code snippet:
public class ReverseUsingXOR {
public static void main(String[] args) {
String str = "prateek";
reverseUsingXOR(str.toCharArray());
}
/*Example:
* str= prateek;
* str[low]=p;
* str[high]=k;
* str[low]=p^k;
* str[high]=(p^k)^k =p;
* str[low]=(p^k)^p=k;
*
* */
public static void reverseUsingXOR(char[] str) {
int low = 0;
int high = str.length - 1;
while (low < high) {
str[low] = (char) (str[low] ^ str[high]);
str[high] = (char) (str[low] ^ str[high]);
str[low] = (char) (str[low] ^ str[high]);
low++;
high--;
}
//display reversed string
for (int i = 0; i < str.length; i++) {
System.out.print(str[i]);
}
}
}
Output:
keetarp
As others have pointed out the preferred way is to use:
new StringBuilder(hi).reverse().toString()
But if you want to implement this by yourself, I'm afraid that the rest of responses have flaws.
The reason is that String represents a list of Unicode points, encoded in a char[] array according to the variable-length encoding: UTF-16.
This means some code points use a single element of the array (one code unit) but others use two of them, so there might be pairs of characters that must be treated as a single unit (consecutive "high" and "low" surrogates).
public static String reverseString(String s) {
char[] chars = new char[s.length()];
boolean twoCharCodepoint = false;
for (int i = 0; i < s.length(); i++) {
chars[s.length() - 1 - i] = s.charAt(i);
if (twoCharCodepoint) {
swap(chars, s.length() - 1 - i, s.length() - i);
}
twoCharCodepoint = !Character.isBmpCodePoint(s.codePointAt(i));
}
return new String(chars);
}
private static void swap(char[] array, int i, int j) {
char temp = array[i];
array[i] = array[j];
array[j] = temp;
}
public static void main(String[] args) throws Exception {
FileOutputStream fos = new FileOutputStream("C:/temp/reverse-string.txt");
StringBuilder sb = new StringBuilder("Linear B Syllable B008 A: ");
sb.appendCodePoint(65536); //http://unicode-table.com/es/#10000
sb.append(".");
fos.write(sb.toString().getBytes("UTF-16"));
fos.write("\n".getBytes("UTF-16"));
fos.write(reverseString(sb.toString()).getBytes("UTF-16"));
}
Using charAt() method
String name = "gaurav";
String reversedString = "";
for(int i = name.length()-1; i>=0; i--){
reversedString = reversedString + name.charAt(i);
}
System.out.println(reversedString);
Using toCharArray() method
String name = "gaurav";
char [] stringCharArray = name.toCharArray();
String reversedString = "";
for(int i = stringCharArray.length-1; i>=0; i--) {
reversedString = reversedString + stringCharArray[i];
}
System.out.println(reversedString);
Using reverse() method of the Stringbuilder
String name = "gaurav";
String reversedString = new StringBuilder(name).reverse().toString();
System.out.println(reversedString);
Check https://coderolls.com/reverse-a-string-in-java/
It is very simple in minimum code of lines
public class ReverseString {
public static void main(String[] args) {
String s1 = "neelendra";
for(int i=s1.length()-1;i>=0;i--)
{
System.out.print(s1.charAt(i));
}
}
}
This did the trick for me
public static void main(String[] args) {
String text = "abcdefghijklmnopqrstuvwxyz";
for (int i = (text.length() - 1); i >= 0; i--) {
System.out.print(text.charAt(i));
}
}
1. Using Character Array:
public String reverseString(String inputString) {
char[] inputStringArray = inputString.toCharArray();
String reverseString = "";
for (int i = inputStringArray.length - 1; i >= 0; i--) {
reverseString += inputStringArray[i];
}
return reverseString;
}
2. Using StringBuilder:
public String reverseString(String inputString) {
StringBuilder stringBuilder = new StringBuilder(inputString);
stringBuilder = stringBuilder.reverse();
return stringBuilder.toString();
}
OR
return new StringBuilder(inputString).reverse().toString();
System.out.print("Please enter your name: ");
String name = keyboard.nextLine();
String reverse = new StringBuffer(name).reverse().toString();
String rev = reverse.toLowerCase();
System.out.println(rev);
I used this method to turn names backwards and into lower case.
One natural way to reverse a String is to use a StringTokenizer and a stack. Stack is a class that implements an easy-to-use last-in, first-out (LIFO) stack of objects.
String s = "Hello My name is Sufiyan";
Put it in the stack frontwards
Stack<String> myStack = new Stack<>();
StringTokenizer st = new StringTokenizer(s);
while (st.hasMoreTokens()) {
myStack.push(st.nextToken());
}
Print the stack backwards
System.out.print('"' + s + '"' + " backwards by word is:\n\t\"");
while (!myStack.empty()) {
System.out.print(myStack.pop());
System.out.print(' ');
}
System.out.println('"');
public String reverse(String s) {
String reversedString = "";
for(int i=s.length(); i>0; i--) {
reversedString += s.charAt(i-1);
}
return reversedString;
}
public class Test {
public static void main(String args[]) {
StringBuffer buffer = new StringBuffer("Game Plan");
buffer.reverse();
System.out.println(buffer);
}
}
All above solution is too good but here I am making reverse string using recursive programming.
This is helpful for who is looking recursive way of doing reverse string.
public class ReversString {
public static void main(String args[]) {
char s[] = "Dhiral Pandya".toCharArray();
String r = new String(reverse(0, s));
System.out.println(r);
}
public static char[] reverse(int i, char source[]) {
if (source.length / 2 == i) {
return source;
}
char t = source[i];
source[i] = source[source.length - 1 - i];
source[source.length - 1 - i] = t;
i++;
return reverse(i, source);
}
}
You can also try this:
public class StringReverse {
public static void main(String[] args) {
String str = "Dogs hates cats";
StringBuffer sb = new StringBuffer(str);
System.out.println(sb.reverse());
}
}
Procedure :
We can use split() to split the string .Then use reverse loop and add the characters.
Code snippet:
class test
{
public static void main(String args[])
{
String str = "world";
String[] split= str.split("");
String revers = "";
for (int i = split.length-1; i>=0; i--)
{
revers += split[i];
}
System.out.printf("%s", revers);
}
}
//output : dlrow
It gets the value you typed and returns it reversed ;)
public static String reverse (String a){
char[] rarray = a.toCharArray();
String finalvalue = "";
for (int i = 0; i < rarray.length; i++)
{
finalvalue += rarray[rarray.length - 1 - i];
}
return finalvalue;
}
public String reverseWords(String s) {
String reversedWords = "";
if(s.length()<=0) {
return reversedWords;
}else if(s.length() == 1){
if(s == " "){
return "";
}
return s;
}
char arr[] = s.toCharArray();
int j = arr.length-1;
while(j >= 0 ){
if( arr[j] == ' '){
reversedWords+=arr[j];
}else{
String temp="";
while(j>=0 && arr[j] != ' '){
temp+=arr[j];
j--;
}
j++;
temp = reverseWord(temp);
reversedWords+=temp;
}
j--;
}
String[] chk = reversedWords.split(" ");
if(chk == null || chk.length == 0){
return "";
}
return reversedWords;
}
public String reverseWord(String s){
char[] arr = s.toCharArray();
for(int i=0,j=arr.length-1;i<=j;i++,j--){
char tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
}
return String.valueOf(arr);
}
public static void main(String[] args) {
String str = "Prashant";
int len = str.length();
char[] c = new char[len];
for (int j = len - 1, i = 0; j >= 0; j--, i++) {
c[i] = str.charAt(j);
}
str = String.copyValueOf(c);
System.out.println(str);
}
public void reverString(){
System.out.println("Enter value");
BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
try{
String str=br.readLine();
char[] charArray=str.toCharArray();
for(int i=charArray.length-1; i>=0; i--){
System.out.println(charArray[i]);
}
}
catch(IOException ex){
}
recursion:
public String stringReverse(String string) {
if (string == null || string.length() == 0) {
return string;
}
return stringReverse(string.substring(1)) + string.charAt(0);
}
Sequence of characters (or) StringString's Family:
String testString = "Yashwanth#777"; // ~1 1⁄4→D800₁₆«2²⁰
Using Java 8 Stream API
First we convert String into stream by using method CharSequence.chars(), then we use the method IntStream.range to generate a sequential stream of numbers. Then we map this sequence of stream into String.
public static String reverseString_Stream(String str) {
IntStream cahrStream = str.chars();
final int[] array = cahrStream.map( x -> x ).toArray();
int from = 0, upTo = array.length;
IntFunction<String> reverseMapper = (i) -> ( Character.toString((char) array[ (upTo - i) + (from - 1) ]) );
String reverseString = IntStream.range(from, upTo) // for (int i = from; i < upTo ; i++) { ... }
.mapToObj( reverseMapper ) // array[ lastElement ]
.collect(Collectors.joining()) // Joining stream of elements together into a String.
.toString(); // This object (which is already a string!) is itself returned.
System.out.println("Reverse Stream as String : "+ reverseString);
return reverseString;
}
Using a Traditional for Loop
If you want to reverse the string then we need to follow these steps.
Convert String into an Array of Characters.
Iterate over an array in reverse order, append each Character to temporary string variable until the last character.
public static String reverseString( String reverse ) {
if( reverse != null && reverse != "" && reverse.length() > 0 ) {
char[] arr = reverse.toCharArray();
String temp = "";
for( int i = arr.length-1; i >= 0; i-- ) {
temp += arr[i];
}
System.out.println("Reverse String : "+ temp);
}
return null;
}
Easy way to Use reverse method provided form StringBuffer or StringBuilder Classes
StringBuilder and StringBuffer are mutable sequence of characters. That means one can change the value of these object's.
StringBuffer buffer = new StringBuffer(str);
System.out.println("StringBuffer - reverse : "+ buffer.reverse() );
String builderString = (new StringBuilder(str)).reverse().toString;
System.out.println("StringBuilder generated reverse String : "+ builderString );
StringBuffer has the same methods as the StringBuilder, but each method in StringBuffer is synchronized so it is thread safe.
public static String revString(String str){
char[] revCharArr = str.toCharArray();
for (int i=0; i< str.length()/2; i++){
char f = revCharArr[i];
char l = revCharArr[str.length()-i-1];
revCharArr[i] = l;
revCharArr[str.length()-i-1] = f;
}
String revStr = new String(revCharArr);
return revStr;
}
Simple For loop in java
public void reverseString(char[] s) {
int length = s.length;
for (int i = 0; i < s.length / 2; i++) {
// swaping character
char temp = s[length - i - 1];
s[length - i - 1] = s[i];
s[i] = temp;
}
}
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();
}
I have seven strings in a program named string1 through string7.
The size of each of the string will be 30 characters.
I will get a input string of unknown length.
I have to split this input string in 30 char strings and then set first substring into string1, 2nd in string2 and so on until possible. If input string is greater then 210 characters then remaining string at the end will be ignored.
How to handle the case when the input string is of size smaller then 210 char.
For e.g. 145 in which case string1 through string4 will be full and string5 will be made of remaining 15 char.
How to handle this nicely ?
I can do it reading char by char and putting first 30 char and string1, next in string2, etc until all char are consumed.
But is there a better way to do this ?
If you can use third-party libraries, with Guava this is just
Iterable<String> chunks = Splitter.fixedLength(30).split(string);
This can be converted to a List<String> with e.g. Lists.newArrayList.
(Disclosure: I contribute to Guava.)
private static Collection<String> splitStringBySize(String str, int size) {
ArrayList<String> split = new ArrayList<>();
for (int i = 0; i <= str.length() / size; i++) {
split.add(str.substring(i * size, Math.min((i + 1) * size, str.length())));
}
return split;
}
Since your Strings are not in an array or List you need to assign them explicitely.
Matcher m = Pattern.compile(".{1,30}").matcher(s);
String s1 = m.find() ? s.substring(m.start(), m.end()) : "";
String s2 = m.find() ? s.substring(m.start(), m.end()) : "";
String s3 = m.find() ? s.substring(m.start(), m.end()) : "";
String s4 = m.find() ? s.substring(m.start(), m.end()) : "";
String s5 = m.find() ? s.substring(m.start(), m.end()) : "";
String s6 = m.find() ? s.substring(m.start(), m.end()) : "";
String s7 = m.find() ? s.substring(m.start(), m.end()) : "";
How about using a char array for splitting the string, create a general-use method receiving the chunk size and maximum size to consider, and returning a String array?
public class SplitStringIntoFixedSizeChunks {
public static String[] Split(String text, int chunkSize, int maxLength) {
char[] data = text.toCharArray();
int len = Math.min(data.length,maxLength);
String[] result = new String[(len+chunkSize-1)/chunkSize];
int linha = 0;
for (int i=0; i < len; i+=chunkSize) {
result[linha] = new String(data, i, Math.min(chunkSize,len-i));
linha++;
}
return result;
}
public static void main(String[] args) {
String x = "flskdafsld~fdsakçkçfsda sfdaldsak~çfdskkfadsçlkçfldskçlflçfdskçldksçlkfdslçakafdslçdsklçfdskçlafdskçkdfsçlkfds~çlkfasdçlçfdls~kçlf~dksçlsakdçlkfç";
System.out.println("x length: "+x.length());
String[] lines = Split(x, 30, 210);
for (int i=0; i < lines.length; i++) {
System.out.println("lines["+i+"]: (len: "+lines[i].length()+") : "+lines[i]);
}
}
}
This example results:
x length: 145
lines[0]: (len: 30) : flskdafsld~fdsakçkçfsda sfdald
lines[1]: (len: 30) : sak~çfdskkfadsçlkçfldskçlflçfd
lines[2]: (len: 30) : skçldksçlkfdslçakafdslçdsklçfd
lines[3]: (len: 30) : skçlafdskçkdfsçlkfds~çlkfasdçl
lines[4]: (len: 25) : çfdls~kçlf~dksçlsakdçlkfç
This is something which should work:
String str = "11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111";
if (str.length() > 210)
{
str = str.substring(0, 209);
}
String newStr = str.replaceAll("(.{30})", "$1|");
System.out.println(newStr);
String[] newStrings = newStr.split("\\|");
What it does is that it takes the given string and at every 30 characters, it throws in a seperator. In this case, I am assuming that you have an idea of what will the user enter and what not so that you can throw in a seperator (or group of seperators) which the user will not enter. Once I do that, I split the string using the seperator I have just added.
This might help you.
public static void main(String args[]) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String st = br.readLine();
int len = st.length();
String[] str = new String[7];
len=len/30;
int i=0;
for(; i<7 && i<len; i++ ){
str[i] = st.substring(30*i, 30*(i+1));
System.out.println(str[i]);
}
if(i!=7){
str[i] = st.substring(30*i, st.length());
System.out.println(str[i]);
}
}
I ran into an issue with a specific usage of this technique. A user was copy/pasting M$ Word content into an HTML field that eventually was picked up by this technique to be split into multiple database fields.
The technique broke against M$ Word's use of carriage returns and other ASCII characters. The REGEX would split off each carriage return instead of a specified number of characters. To correct the issue, I modified Michael Besteck's code to the following:
Matcher m = Pattern.compile(".{1,30}", Pattern.DOTALL).matcher(s);
String s1 = m.find() ? s.substring(m.start(), m.end()) : "";
String s2 = m.find() ? s.substring(m.start(), m.end()) : "";
String s3 = m.find() ? s.substring(m.start(), m.end()) : "";
String s4 = m.find() ? s.substring(m.start(), m.end()) : "";
String s5 = m.find() ? s.substring(m.start(), m.end()) : "";
String s6 = m.find() ? s.substring(m.start(), m.end()) : "";
String s7 = m.find() ? s.substring(m.start(), m.end()) : "";
This accounts for the ASCII characters correctly.
This is what I did. Seems to work. Please comment if I am wrong anywhere:
package com.mypackage;
import java.util.ArrayList;
import java.util.List;
public class TestClass {
public static List<String> splitEqually(final String text, final int size) {
List<String> ret = new ArrayList<String>((text.length() + size - 1) / size);
for (int start = 0; start < text.length(); start += size) {
if (start + size > 0) {
String temp = text.substring(start, Math.min(text.length(), start + size));
int length = temp.length();
for (int i = 0; i < (size - length); i++) {
temp = temp + " ";
}
ret.add(temp);
} else {
ret.add(text.substring(start, Math.min(text.length(), start + size)));
}
}
return ret;
}
public static void main(final String args[]) {
String input = "hello wo";
String str1, str2, str3, str4, str5;
List<String> result = TestClass.splitEqually(input, 3);
try {
str1 = result.get(0);
System.out.println("1: " + result.get(0));
str2 = result.get(1);
System.out.println("2: " + result.get(1));
str3 = result.get(2);
System.out.println("3: " + result.get(2));
str4 = result.get(3);
System.out.println("4: " + result.get(3));
str5 = result.get(4);
System.out.println("5: " + result.get(4));
} catch (IndexOutOfBoundsException e) {
}
}
}
import java.util.ArrayList;
public class Test {
public static void main(String[] args) {
// your input
String input = "";
// strings 1-7 as array list
ArrayList<String> results = new ArrayList<String>();
int length;
if(input.length() > 210) {
length = 210;
} else {
length = input.length();
}
for(int i = 0; i <= length; i += 30) {
if((length - (i + 30)) > 0) {
results.add(input.substring(i, i + 30));
} else {
results.add(input.substring(i, length));
}
}
for(int a = 0; a < results.size(); a++) {
System.out.println("size: " + results.get(a).length() + " content: " + results.get(a));
}
}
}
private Collection<String> splitStringBySize(String strPrm, int sizePrm) {
ArrayList<String> splitLcl = new ArrayList<>();
int lLcl=strPrm.length();
int quantityLcl = lLcl / sizePrm;
for (int i = 0; i < quantityLcl; i++) {
splitLcl.add(strPrm.substring(i * sizePrm,(i+1) * sizePrm ));
}
int tailLcl = lLcl % sizePrm;
if(tailLcl>0){
splitLcl.add(strPrm.substring(lLcl-tailLcl,lLcl));
}
return splitLcl;
}
Using Streams, this one should do it in an easy way:
private static Stream<String> splitToFixedSize(String input, int maxSize) {
var noOfChunks = (int) Math.ceil((float) input.length() / maxSize);
return IntStream.range(0, noOfChunks).mapToObj(i -> {
var start = i * maxSize;
var end = Math.min((i + 1) * maxSize, input.length());
return input.substring(start, end);
});
}
I have a question about a programming problem from the book Cracking The Code Interview by Gayl Laakmann McDowell, 5th Edition.
The problem states: Write a method to replace all spaces in a string with '%20'. Assume string has sufficient space at end of string to hold additional characters, and that you're given a true length of a string. I used the books code, implementing the solution in Java using a character array (given the fact that Java Strings are immutable):
public class Test {
public void replaceSpaces(char[] str, int length) {
int spaceCount = 0, newLength = 0, i = 0;
for(i = 0; i < length; i++) {
if (str[i] == ' ')
spaceCount++;
}
newLength = length + (spaceCount * 2);
str[newLength] = '\0';
for(i = length - 1; i >= 0; i--) {
if (str[i] == ' ') {
str[newLength - 1] = '0';
str[newLength - 2] = '2';
str[newLength - 3] = '%';
newLength = newLength - 3;
}
else {
str[newLength - 1] = str[i];
newLength = newLength - 1;
}
}
System.out.println(str);
}
public static void main(String[] args) {
Test tst = new Test();
char[] ch = {'t', 'h', 'e', ' ', 'd', 'o', 'g', ' ', ' ', ' ', ' ', ' ', ' '};
int length = 6;
tst.replaceSpaces(ch, length);
}
}
The output I am getting from the replaceSpaces() call is: the%20do which is cutting of the last character of the original array. I have been scratching my head over this, can anyone explain to me why the algorithm is doing this?
public String replace(String str) {
String[] words = str.split(" ");
StringBuilder sentence = new StringBuilder(words[0]);
for (int i = 1; i < words.length; ++i) {
sentence.append("%20");
sentence.append(words[i]);
}
return sentence.toString();
}
You are passing the length as 6, which is causing this. Pass length as 7 including space.
Other wise
for(i = length - 1; i >= 0; i--) {
will not consider last char.
With these two changes I got the output: the%20dog
1) Change space count to 2 [since length already includes 1 of the 3 characters you need for %20]
newLength = length + (spaceCount * 2);
2) Loop should start on length
for(i = length; i >= 0; i--) {
Here is my solution. I check for the ascii code 32 then put a %20 instead of it.Time complexity of this solution is O(N)
public String replace(String s) {
char arr[] = s.toCharArray();
StringBuilder sb = new StringBuilder();
for (int i = 0; i < arr.length; i++) {
if (arr[i] == 32)
sb.append("%20");
else
sb.append(arr[i]);
}
return sb.toString();
}
This is my code for this question. Seems like working for me. If you're interested, please have a look. It's written in JAVA
public class ReplaceSpaceInString {
private static char[] replaceSpaceInString(char[] str, int length) {
int spaceCounter = 0;
//First lets calculate number of spaces
for (int i = 0; i < length; i++) {
if (str[i] == ' ')
spaceCounter++;
}
//calculate new size
int newLength = length + 2*spaceCounter;
char[] newArray = new char[newLength+1];
newArray[newLength] = '\0';
int newArrayPosition = 0;
for (int i = 0; i < length; i++) {
if (str[i] == ' ') {
newArray[newArrayPosition] = '%';
newArray[newArrayPosition+1] = '2';
newArray[newArrayPosition+2] = '0';
newArrayPosition = newArrayPosition + 3;
}
else {
newArray[newArrayPosition] = str[i];
newArrayPosition++;
}
}
return newArray;
}
public static void main(String[] args) {
char[] array = {'a','b','c','d',' ','e','f','g',' ','h',' ','j'};
System.out.println(replaceSpaceInString(array, array.length));
}
}
You can also use substring method and the ascii for space (32).
public String replaceSpaceInString(String s){
int i;
for (i=0;i<s.length();i++){
System.out.println("i is "+i);
if (s.charAt(i)==(int)32){
s=s.substring(0, i)+"%20"+s.substring(i+1, s.length());
i=i+2;
}
}
return s;
}
To test:
System.out.println(cc.replaceSpaceInString("mon day "));
Output:
mon%20day%20
You could just do this.
No need to calculate the length or whatever.
Strings are immutable anyways.
import java.util.*;
public class ReplaceString {
public static void main(String[] args) {
Scanner in=new Scanner(System.in);
String str=in.nextLine();
String n="";
for(int i=0;i<str.length();i++)
{
if(str.charAt(i)==' ')
n=n+"%20";
else
n=n+str.charAt(i);
}
str=n;
System.out.println(str);
}
}
void Rep_Str(char *str)
{
int j=0,count=0;
int stlen = strlen(str);
for (j = 0; j < stlen; j++)
{
if (str[j]==' ')
{
count++;
}
}
int newlength = stlen+(count*2);
str[newlength--]='\0';
for (j = stlen-1; j >=0 ; j--)
{
if (str[j]==' ')
{
str[newlength--]='0';
str[newlength--]='2';
str[newlength--]='%';
}
else
{
str[newlength--]=str[j];
}
}
}
This code works :)
We can use a regular expression to solve this problem. For example:
public String replaceStringWithSpace(String str){
return str.replaceAll("[\\s]", "%20");
}
This works correctly. However, using a StringBuffer object increases space complexity.
Scanner scn = new Scanner(System.in);
String str = scn.nextLine();
StringBuffer sb = new StringBuffer(str.trim());
for(int i = 0;i<sb.length();i++){
if(32 == (int)sb.charAt(i)){
sb.replace(i,i+1, "%20");
}
}
public static String replaceAllSpaces(String s) {
char[] c = s.toCharArray();
int spaceCount = 0;
int trueLen = s.length();
int index = 0;
for (int i = 0; i < trueLen; i++) {
if (c[i] == ' ') {
spaceCount++;
}
}
index = trueLen + spaceCount * 2;
char[] n = new char[index];
for (int i = trueLen - 1; i >= 0; i--) {
if (c[i] == ' ') {
n[index - 1] = '0';
n[index - 2] = '2';
n[index - 3] = '%';
index = index - 3;
} else {
n[index - 1] = c[i];
index--;
}
}
String x = new String(n);
return x;
}
Another way of doing this.
I am assuming the trailing spaces don't need to be converted to %20 and that the trailing spaces provide enough room for %20s to be stuffed in between
public class Main {
public static void main(String[] args) {
String str = "a sd fghj ";
System.out.println(replacement(str));//a%20sd%20fghj
}
private static String replacement(String str) {
char[] chars = str.toCharArray();
int posOfLastChar = 0;
for (int i = 0; i < chars.length; i++) {
if (chars[i] != ' ') {
posOfLastChar = i;
}
}
int newCharPosition = chars.length - 1;
//Start moving the characters to th end of the array. Replace spaces by %20
for (int i = posOfLastChar; i >= 0; i--) {
if (chars[i] == ' ') {
chars[newCharPosition] = '0';
chars[--newCharPosition] = '2';
chars[--newCharPosition] = '%';
} else {
chars[newCharPosition] = chars[i];
}
newCharPosition--;
}
return String.valueOf(chars);
}
}
public class ReplaceChar{
public static void main(String []args){
String s = "ab c de ";
System.out.println(replaceChar(s));
}
public static String replaceChar(String s){
boolean found = false;
StringBuilder res = new StringBuilder(50);
String str = rev(s);
for(int i = 0; i <str.length(); i++){
if (str.charAt(i) != ' ') { found = true; }
if (str.charAt(i) == ' '&& found == true) { res.append("%02"); }
else{ res.append(str.charAt(i)); }
}
return rev(res.toString());
}
// Function to reverse a string
public static String rev(String s){
StringBuilder result = new StringBuilder(50);
for(int i = s.length()-1; i>=0; i-- ){
result.append(s.charAt(i));
}
return result.toString();
}}
A simple approach:
Reverse the given string and check where the first character appears.
Using string builder to append "02%" for spaces - since the string is reversed.
Finally reverse the string once again.
Note: We reverse the string so as to prevent an addition of "%20" to the trailing spaces.
Hope that helps!
The question in the book mentions that the replacement should be in place so it is not possible to assign extra arrays, it should use constant space. You should also take into account many edge cases, this is my solution:
public class ReplaceSpaces {
public static void main(String[] args) {
if ( args.length == 0 ) {
throw new IllegalArgumentException("No string");
}
String s = args[0];
char[] characters = s.toCharArray();
replaceSpaces(characters);
System.out.println(characters);
}
static void replaceSpaces(char[] s) {
int i = s.length-1;
//Skipping all spaces in the end until setting `i` to non-space character
while( i >= 0 && s[i] == ' ' ) { i--; }
/* Used later to check there is enough extra space in the end */
int extraSpaceLength = s.length - i - 1;
/*
Used when moving the words right,
instead of finding the first non-space character again
*/
int lastNonSpaceCharacter = i;
/*
Hold the number of spaces in the actual string boundaries
*/
int numSpaces = 0;
/*
Counting num spaces beside the extra spaces
*/
while( i >= 0 ) {
if ( s[i] == ' ' ) { numSpaces++; }
i--;
}
if ( numSpaces == 0 ) {
return;
}
/*
Throw exception if there is not enough space
*/
if ( extraSpaceLength < numSpaces*2 ) {
throw new IllegalArgumentException("Not enough extra space");
}
/*
Now we need to move each word right in order to have space for the
ascii representation
*/
int wordEnd = lastNonSpaceCharacter;
int wordsCounter = 0;
int j = wordEnd - 1;
while( j >= 0 ) {
if ( s[j] == ' ' ){
moveWordRight(s, j+1, wordEnd, (numSpaces-wordsCounter)*2);
wordsCounter++;
wordEnd = j;
}
j--;
}
replaceSpacesWithAscii(s, lastNonSpaceCharacter + numSpaces * 2);
}
/*
Replaces each 3 sequential spaces with %20
char[] s - original character array
int maxIndex - used to tell the method what is the last index it should
try to replace, after that is is all extra spaces not required
*/
static void replaceSpacesWithAscii(char[] s, int maxIndex) {
int i = 0;
while ( i <= maxIndex ) {
if ( s[i] == ' ' ) {
s[i] = '%';
s[i+1] = '2';
s[i+2] = '0';
i+=2;
}
i++;
}
}
/*
Move each word in the characters array by x moves
char[] s - original character array
int startIndex - word first character index
int endIndex - word last character index
int moves - number of moves to the right
*/
static void moveWordRight(char[] s, int startIndex, int endIndex, int moves) {
for(int i=endIndex; i>=startIndex; i--) {
s[i+moves] = s[i];
s[i] = ' ';
}
}
}
Any reason not to use 'replace' method?
public String replaceSpaces(String s){
return s.replace(" ", "%20");}
Hm... I am wondering about this problem as well. Considering what I have seen in here. The book solution does not fit Java because it uses in-place
char []
modification and solutions in here that use char [] or return void don't fit as well because Java does not use pointers.
So I was thinking, the obvious solution would be
private static String encodeSpace(String string) {
return string.replcaceAll(" ", "%20");
}
but this is probably not what your interviewer would like to see :)
// make a function that actually does something
private static String encodeSpace(String string) {
//create a new String
String result = new String();
// replacement
final String encodeSpace = "%20";
for(char c : string.toCharArray()) {
if(c == ' ') result+=encodeString;
else result+=c;
}
return result;
}
this looks fine I thought, and you only need one pass through the string, so the complexity should be O(n), right? Wrong! The problem is in
result += c;
which is the same as
result = result + c;
which actually copies a string and creates a copy of it. In java strings are represented as
private final char value[];
which makes them immutable (for more info I would check java.lang.String and how it works). This fact will bump up the complexity of this algorithm to O(N^2) and a sneaky recruiter can use this fact to fail you :P Thus, I came in with a new low-level solution which you will never use in practice, but which is good in theory :)
private static String encodeSpace(String string) {
final char [] original = string != null? string.toCharArray() : new char[0];
// ASCII encoding
final char mod = 37, two = 50, zero = 48, space = 32;
int spaces = 0, index = 0;
// count spaces
for(char c : original) if(c == space) ++spaces;
// if no spaces - we are done
if(spaces == 0) return string;
// make a new char array (each space now takes +2 spots)
char [] result = new char[string.length()+(2*spaces)];
for(char c : original) {
if(c == space) {
result[index] = mod;
result[++index] = two;
result[++index] = zero;
}
else result[index] = c;
++index;
}
return new String(result);
}
But I wonder what is wrong with following code:
private static String urlify(String originalString) {
String newString = "";
if (originalString.contains(" ")) {
newString = originalString.replace(" ", "%20");
}
return newString;
}
Question : Urlify the spaces with %20
Solution 1 :
public class Solution9 {
public static void main(String[] args) {
String a = "Gini Gina Protijayi";
System.out.println( urlencode(a));
}//main
public static String urlencode(String str) {
str = str.trim();
System.out.println("trim =>" + str);
if (!str.contains(" ")) {
return str;
}
char[] ca = str.toCharArray();
int spaces = 0;
for (char c : ca) {
if (c == ' ') {
spaces++;
}
}
char[] newca = new char[ca.length + 2 * spaces];
// a pointer x has been added
for (int i = 0, x = 0; i < ca.length; i++) {
char c = ca[i];
if (c == ' ') {
newca[x] = '%';
newca[x + 1] = '2';
newca[x + 2] = '0';
x += 3;
} else {
newca[x] = c;
x++;
}
}
return new String(newca);
}
}//urlify
My solution using StringBuilder with time complexity O(n)
public static String url(String string, int length) {
char[] arrays = string.toCharArray();
StringBuilder builder = new StringBuilder(length);
for (int i = 0; i < length; i++) {
if (arrays[i] == ' ') {
builder.append("%20");
} else {
builder.append(arrays[i]);
}
}
return builder.toString();
}
Test case :
#Test
public void testUrl() {
assertEquals("Mr%20John%20Smith", URLify.url("Mr John Smith ", 13));
}
Can you use StringBuilder?
public String replaceSpace(String s)
{
StringBuilder answer = new StringBuilder();
for(int i = 0; i<s.length(); i++)
{
if(s.CharAt(i) == ' ')
{
answer.append("%20");
}
else
{
answer.append(s.CharAt(i));
}
}
return answer.toString();
}
I am also looking at that question in the book. I believe we can just use String.trim() and String.replaceAll(" ", "%20) here
I updated the solution here. http://rextester.com/CWAPCV11970
If we are creating new array and not in-place trasition, then why do we need to walk backwards?
I modified the real solution slightly to walk forward to create target Url-encoded-string.
Time complexity:
O(n) - Walking original string
O(1) - Creating target string incrementally
where 'n' is number of chars in original string
Space complexity:
O(n + m) - Duplicate space to store escaped spaces and string.
where 'n' is number of chars in original string and 'm' is length of escaped spaces
public static string ReplaceAll(string originalString, char findWhat, string replaceWith)
{
var newString = string.Empty;
foreach(var character in originalString)
newString += findWhat == character? replaceWith : character + string.Empty;
return newString;
}
class Program
{
static void Main(string[] args)
{
string name = "Stack Over Flow ";
StringBuilder stringBuilder = new StringBuilder();
char[] array = name.ToCharArray(); ;
for(int i = 0; i < name.Length; i++)
{
if (array[i] == ' ')
{
stringBuilder.Append("%20");
}
else
stringBuilder.Append(array[i]);
}
Console.WriteLine(stringBuilder);
Console.ReadLine();
}
}
public class Sol {
public static void main(String[] args) {
String[] str = "Write a method to replace all spaces in a string with".split(" ");
StringBuffer sb = new StringBuffer();
int count = 0;
for(String s : str){
sb.append(s);
if(str.length-1 != count)
sb.append("%20");
++count;
}
System.out.println(sb.toString());
}
}
public class Test {
public static void replace(String str) {
String[] words = str.split(" ");
StringBuilder sentence = new StringBuilder(words[0]);
for (int i = 1; i < words.length; i++) {
sentence.append("%20");
sentence.append(words[i]);
}
sentence.append("%20");
System.out.println(sentence.toString());
}
public static void main(String[] args) {
replace("Hello World "); **<- Hello<3spaces>World<1space>**
}
}
O/P:: Hello%20%20%20World%20
Remember that you only to want replace ' ' with '%20' when the latter is not a leading or trailing space. Several answers above do not account for this. For what it's worth, I get "index out of bounds error" when I run Laakmann's solution example.
Here's my own solution, which runs O(n) and is implemented in C#:
public static string URLreplace(string str, int n)
{
var len = str.Length;
if (len == n)
return str;
var sb = new StringBuilder();
var i = 0;
while (i < len)
{
char c = str[i];
if (c == ' ')
{
while (i < len && str[i] == ' ')
{
i++; //skip ahead
}
}
else
{
if (sb.Length > 0 && str[i - 1] == ' ')
sb.Append("%20" + c);
else
sb.Append(c);
i++;
}
}
return sb.ToString();
}
Test:
//Arrange
private string _str = " Mr John Smith ";
private string _result = "Mr%20John%20Smith";
private int _int = 13;
[TestMethod]
public void URLified()
{
//Act
var cleaned = URLify.URLreplace(_str, _int);
//Assert
Assert.IsTrue(cleaned == _result);
}
One line code
System.out.println(s.trim().replace(" ","%20"));
// while passing the input make sure you use the .toCharArray method becuase strings are immutable
public static void replaceSpaces(char[] str, int length) {
int spaceCount = 0, newLength = 0, i = 0;
for (i = 0; i < length; i++) {
if (str[i] == ' ')
spaceCount++;
}
newLength = length + (spaceCount * 2);
// str[newLength] = '\0';
for (i = length - 1; i >= 0; i--) {
if (str[i] == ' ') {
str[newLength - 1] = '0';
str[newLength - 2] = '2';
str[newLength - 3] = '%';
newLength = newLength - 3;
} else {
str[newLength - 1] = str[i];
newLength = newLength - 1;
}
}
System.out.println(str);
}
public static void main(String[] args) {
// Test tst = new Test();
char[] ch = "Mr John Smith ".toCharArray();
int length = 13;
replaceSpaces(ch, length);
}
`// Maximum length of string after modifications.
const int MAX = 1000;
// Replaces spaces with %20 in-place and returns
// new length of modified string. It returns -1
// if modified string cannot be stored in str[]
int replaceSpaces(char str[])
{
// count spaces and find current length
int space_count = 0, i;
for (i = 0; str[i]; i++)
if (str[i] == ' ')
space_count++;
// Remove trailing spaces
while (str[i-1] == ' ')
{
space_count--;
i--;
}
// Find new length.
int new_length = i + space_count * 2 + 1;
// New length must be smaller than length
// of string provided.
if (new_length > MAX)
return -1;
// Start filling character from end
int index = new_length - 1;
// Fill string termination.
str[index--] = '\0';
// Fill rest of the string from end
for (int j=i-1; j>=0; j--)
{
// inserts %20 in place of space
if (str[j] == ' ')
{
str[index] = '0';
str[index - 1] = '2';
str[index - 2] = '%';
index = index - 3;
}
else
{
str[index] = str[j];
index--;
}
}
return new_length;
}
// Driver code
int main()
{
char str[MAX] = "Mr John Smith ";
// Prints the replaced string
int new_length = replaceSpaces(str);
for (int i=0; i<new_length; i++)
printf("%c", str[i]);
return 0;
}`