Copying Strings n times for a Java Beginner - java

I'm taking an AP Computer Science course at my school, and wanted to know how to answer this question:
Write a method named copies that, given as arguments a string s and a nonnegative integer n, returns the string formed from concatenating n copies of s.
I've tried this, but you can't multiply strings:
public String copies (String s, int n) {
int copyCount;
copyCount = 0;
while ( n > 0 ) {
s = s * n;
n = n - 1;
}
return s;
}
I know similar question has been answered before, but I'm looking for a way to do this using only if-statements and while loops. Our class hasn't gotten to anything past that so far, so if anybody knows how to do it like this, it would be much appreciated.
UPDATE: I also need to be able to show "" when I use 0 as n.

Something like this should do what you need.
UPDATED to show "" when n = 0
public String copies(String s int n) {
StringBuilder sb = new StringBuilder();
if (n > 0) {
int i = 0;
while (i < n) {
sb.append(s);
i++;
}
}
return sb.toString();
}

Here's one way to do it.
String copies(String s, int n) {
StringBuilder builder = new StringBuilder();
for (int count = 0; count < n; ++count)
builder.append(s);
return builder.toString();
}
I chose to use a for instead of a while (for cleanliness), but you should be able to make any mods you need pretty easily :p

If you want to create int n copies of String s you should try something like this
// Return a String, containing n copies of s.
public static String copies(String s, int n) {
// More then 0?
if (n > 0) {
StringBuilder sb = new StringBuilder();
int i = 0;
while (i < n) {
sb.append(s);
i++;
}
return sb.toString();
}
// Just return the input.
return s;
}

Related

Repeat the content of a String [duplicate]

I'm looking for a simple commons method or operator that allows me to repeat some string n times. I know I could write this using a for loop, but I wish to avoid for loops whenever necessary and a simple direct method should exist somewhere.
String str = "abc";
String repeated = str.repeat(3);
repeated.equals("abcabcabc");
Related to:
repeat string javascript
Create NSString by repeating another string a given number of times
Edited
I try to avoid for loops when they are not completely necessary because:
They add to the number of lines of code even if they are tucked away in another function.
Someone reading my code has to figure out what I am doing in that for loop. Even if it is commented and has meaningful variables names, they still have to make sure it is not doing anything "clever".
Programmers love to put clever things in for loops, even if I write it to "only do what it is intended to do", that does not preclude someone coming along and adding some additional clever "fix".
They are very often easy to get wrong. For loops involving indexes tend to generate off by one bugs.
For loops often reuse the same variables, increasing the chance of really hard to find scoping bugs.
For loops increase the number of places a bug hunter has to look.
Here is the shortest version (Java 1.5+ required):
repeated = new String(new char[n]).replace("\0", s);
Where n is the number of times you want to repeat the string and s is the string to repeat.
No imports or libraries needed.
If you are using Java <= 7, this is as "concise" as it gets:
// create a string made up of n copies of string s
String.format("%0" + n + "d", 0).replace("0", s);
In Java 8 and above there is a more readable way:
// create a string made up of n copies of string s
String.join("", Collections.nCopies(n, s));
Finally, for Java 11 and above, there is a new repeat​(int count) method specifically for this purpose(link)
"abc".repeat(12);
Alternatively, if your project uses java libraries there are more options.
For Apache Commons:
StringUtils.repeat("abc", 12);
For Google Guava:
Strings.repeat("abc", 12);
String::repeat
". ".repeat(7) // Seven period-with-space pairs: . . . . . . .
New in Java 11 is the method String::repeat that does exactly what you asked for:
String str = "abc";
String repeated = str.repeat(3);
repeated.equals("abcabcabc");
Its Javadoc says:
/**
* Returns a string whose value is the concatenation of this
* string repeated {#code count} times.
* <p>
* If this string is empty or count is zero then the empty
* string is returned.
*
* #param count number of times to repeat
*
* #return A string composed of this string repeated
* {#code count} times or the empty string if this
* string is empty or count is zero
*
* #throws IllegalArgumentException if the {#code count} is
* negative.
*
* #since 11
*/
Commons Lang StringUtils.repeat()
Usage:
String str = "abc";
String repeated = StringUtils.repeat(str, 3);
repeated.equals("abcabcabc");
Java 8's String.join provides a tidy way to do this in conjunction with Collections.nCopies:
// say hello 100 times
System.out.println(String.join("", Collections.nCopies(100, "hello")));
Here's a way to do it using only standard String functions and no explicit loops:
// create a string made up of n copies of s
repeated = String.format(String.format("%%%ds", n), " ").replace(" ",s);
If you're like me and want to use Google Guava and not Apache Commons. You can use the repeat method in the Guava Strings class.
Strings.repeat("-", 60);
With java-8, you can also use Stream.generate.
import static java.util.stream.Collectors.joining;
...
String repeated = Stream.generate(() -> "abc").limit(3).collect(joining()); //"abcabcabc"
and you can wrap it in a simple utility method if needed:
public static String repeat(String str, int times) {
return Stream.generate(() -> str).limit(times).collect(joining());
}
So you want to avoid loops?
Here you have it:
public static String repeat(String s, int times) {
if (times <= 0) return "";
else return s + repeat(s, times-1);
}
(of course I know this is ugly and inefficient, but it doesn't have loops :-p)
You want it simpler and prettier? use jython:
s * 3
Edit: let's optimize it a little bit :-D
public static String repeat(String s, int times) {
if (times <= 0) return "";
else if (times % 2 == 0) return repeat(s+s, times/2);
else return s + repeat(s+s, times/2);
}
Edit2: I've done a quick and dirty benchmark for the 4 main alternatives, but I don't have time to run it several times to get the means and plot the times for several inputs... So here's the code if anybody wants to try it:
public class Repeat {
public static void main(String[] args) {
int n = Integer.parseInt(args[0]);
String s = args[1];
int l = s.length();
long start, end;
start = System.currentTimeMillis();
for (int i = 0; i < n; i++) {
if(repeatLog2(s,i).length()!=i*l) throw new RuntimeException();
}
end = System.currentTimeMillis();
System.out.println("RecLog2Concat: " + (end-start) + "ms");
start = System.currentTimeMillis();
for (int i = 0; i < n; i++) {
if(repeatR(s,i).length()!=i*l) throw new RuntimeException();
}
end = System.currentTimeMillis();
System.out.println("RecLinConcat: " + (end-start) + "ms");
start = System.currentTimeMillis();
for (int i = 0; i < n; i++) {
if(repeatIc(s,i).length()!=i*l) throw new RuntimeException();
}
end = System.currentTimeMillis();
System.out.println("IterConcat: " + (end-start) + "ms");
start = System.currentTimeMillis();
for (int i = 0; i < n; i++) {
if(repeatSb(s,i).length()!=i*l) throw new RuntimeException();
}
end = System.currentTimeMillis();
System.out.println("IterStrB: " + (end-start) + "ms");
}
public static String repeatLog2(String s, int times) {
if (times <= 0) {
return "";
}
else if (times % 2 == 0) {
return repeatLog2(s+s, times/2);
}
else {
return s + repeatLog2(s+s, times/2);
}
}
public static String repeatR(String s, int times) {
if (times <= 0) {
return "";
}
else {
return s + repeatR(s, times-1);
}
}
public static String repeatIc(String s, int times) {
String tmp = "";
for (int i = 0; i < times; i++) {
tmp += s;
}
return tmp;
}
public static String repeatSb(String s, int n) {
final StringBuilder sb = new StringBuilder();
for(int i = 0; i < n; i++) {
sb.append(s);
}
return sb.toString();
}
}
It takes 2 arguments, the first is the number of iterations (each function run with repeat times arg from 1..n) and the second is the string to repeat.
So far, a quick inspection of the times running with different inputs leaves the ranking something like this (better to worse):
Iterative StringBuilder append (1x).
Recursive concatenation log2 invocations (~3x).
Recursive concatenation linear invocations (~30x).
Iterative concatenation linear (~45x).
I wouldn't ever guessed that the recursive function was faster than the for loop :-o
Have fun(ctional xD).
This contains less characters than your question
public static String repeat(String s, int n) {
if(s == null) {
return null;
}
final StringBuilder sb = new StringBuilder(s.length() * n);
for(int i = 0; i < n; i++) {
sb.append(s);
}
return sb.toString();
}
based on fortran's answer, this is a recusive version that uses a StringBuilder:
public static void repeat(StringBuilder stringBuilder, String s, int times) {
if (times > 0) {
repeat(stringBuilder.append(s), s, times - 1);
}
}
public static String repeat(String s, int times) {
StringBuilder stringBuilder = new StringBuilder(s.length() * times);
repeat(stringBuilder, s, times);
return stringBuilder.toString();
}
using Dollar is simple as typing:
#Test
public void repeatString() {
String string = "abc";
assertThat($(string).repeat(3).toString(), is("abcabcabc"));
}
PS: repeat works also for array, List, Set, etc
I wanted a function to create a comma-delimited list of question marks for JDBC purposes, and found this post. So, I decided to take two variants and see which one performed better. After 1 million iterations, the garden-variety StringBuilder took 2 seconds (fun1), and the cryptic supposedly more optimal version (fun2) took 30 seconds. What's the point of being cryptic again?
private static String fun1(int size) {
StringBuilder sb = new StringBuilder(size * 2);
for (int i = 0; i < size; i++) {
sb.append(",?");
}
return sb.substring(1);
}
private static String fun2(int size) {
return new String(new char[size]).replaceAll("\0", ",?").substring(1);
}
OOP Solution
Nearly every answer proposes a static function as a solution, but thinking Object-Oriented (for reusability-purposes and clarity) I came up with a Solution via Delegation through the CharSequence-Interface (which also opens up usability on mutable CharSequence-Classes).
The following Class can be used either with or without Separator-String/CharSequence and each call to "toString()" builds the final repeated String.
The Input/Separator are not only limited to String-Class, but can be every Class which implements CharSequence (e.g. StringBuilder, StringBuffer, etc)!
Source-Code:
/**
* Helper-Class for Repeating Strings and other CharSequence-Implementations
* #author Maciej Schuttkowski
*/
public class RepeatingCharSequence implements CharSequence {
final int count;
CharSequence internalCharSeq = "";
CharSequence separator = "";
/**
* CONSTRUCTOR - RepeatingCharSequence
* #param input CharSequence to repeat
* #param count Repeat-Count
*/
public RepeatingCharSequence(CharSequence input, int count) {
if(count < 0)
throw new IllegalArgumentException("Can not repeat String \""+input+"\" less than 0 times! count="+count);
if(count > 0)
internalCharSeq = input;
this.count = count;
}
/**
* CONSTRUCTOR - Strings.RepeatingCharSequence
* #param input CharSequence to repeat
* #param count Repeat-Count
* #param separator Separator-Sequence to use
*/
public RepeatingCharSequence(CharSequence input, int count, CharSequence separator) {
this(input, count);
this.separator = separator;
}
#Override
public CharSequence subSequence(int start, int end) {
checkBounds(start);
checkBounds(end);
int subLen = end - start;
if (subLen < 0) {
throw new IndexOutOfBoundsException("Illegal subSequence-Length: "+subLen);
}
return (start == 0 && end == length()) ? this
: toString().substring(start, subLen);
}
#Override
public int length() {
//We return the total length of our CharSequences with the separator 1 time less than amount of repeats:
return count < 1 ? 0
: ( (internalCharSeq.length()*count) + (separator.length()*(count-1)));
}
#Override
public char charAt(int index) {
final int internalIndex = internalIndex(index);
//Delegate to Separator-CharSequence or Input-CharSequence depending on internal index:
if(internalIndex > internalCharSeq.length()-1) {
return separator.charAt(internalIndex-internalCharSeq.length());
}
return internalCharSeq.charAt(internalIndex);
}
#Override
public String toString() {
return count < 1 ? ""
: new StringBuilder(this).toString();
}
private void checkBounds(int index) {
if(index < 0 || index >= length())
throw new IndexOutOfBoundsException("Index out of Bounds: "+index);
}
private int internalIndex(int index) {
// We need to add 1 Separator-Length to total length before dividing,
// as we subtracted one Separator-Length in "length()"
return index % ((length()+separator.length())/count);
}
}
Usage-Example:
public static void main(String[] args) {
//String input = "12345";
//StringBuffer input = new StringBuffer("12345");
StringBuilder input = new StringBuilder("123");
//String separator = "<=>";
StringBuilder separator = new StringBuilder("<=");//.append('>');
int repeatCount = 2;
CharSequence repSeq = new RepeatingCharSequence(input, repeatCount, separator);
String repStr = repSeq.toString();
System.out.println("Repeat="+repeatCount+"\tSeparator="+separator+"\tInput="+input+"\tLength="+input.length());
System.out.println("CharSeq:\tLength="+repSeq.length()+"\tVal="+repSeq);
System.out.println("String :\tLength="+repStr.length()+"\tVal="+repStr);
//Here comes the Magic with a StringBuilder as Input, as you can append to the String-Builder
//and at the same Time your Repeating-Sequence's toString()-Method returns the updated String :)
input.append("ff");
System.out.println(repSeq);
//Same can be done with the Separator:
separator.append("===").append('>');
System.out.println(repSeq);
}
Example-Output:
Repeat=2 Separator=<= Input=123 Length=3
CharSeq: Length=8 Val=123<=123
String : Length=8 Val=123<=123
123ff<=123ff
123ff<====>123ff
using only JRE classes (System.arraycopy) and trying to minimize the number of temp objects you can write something like:
public static String repeat(String toRepeat, int times) {
if (toRepeat == null) {
toRepeat = "";
}
if (times < 0) {
times = 0;
}
final int length = toRepeat.length();
final int total = length * times;
final char[] src = toRepeat.toCharArray();
char[] dst = new char[total];
for (int i = 0; i < total; i += length) {
System.arraycopy(src, 0, dst, i, length);
}
return String.copyValueOf(dst);
}
EDIT
and without loops you can try with:
public static String repeat2(String toRepeat, int times) {
if (toRepeat == null) {
toRepeat = "";
}
if (times < 0) {
times = 0;
}
String[] copies = new String[times];
Arrays.fill(copies, toRepeat);
return Arrays.toString(copies).
replace("[", "").
replace("]", "").
replaceAll(", ", "");
}
EDIT 2
using Collections is even shorter:
public static String repeat3(String toRepeat, int times) {
return Collections.nCopies(times, toRepeat).
toString().
replace("[", "").
replace("]", "").
replaceAll(", ", "");
}
however I still like the first version.
Not the shortest, but (i think) the fastest way is to use the StringBuilder:
/**
* Repeat a String as many times you need.
*
* #param i - Number of Repeating the String.
* #param s - The String wich you want repeated.
* #return The string n - times.
*/
public static String repeate(int i, String s) {
StringBuilder sb = new StringBuilder();
for (int j = 0; j < i; j++)
sb.append(s);
return sb.toString();
}
If speed is your concern, then you should use as less memory copying as possible. Thus it is required to work with arrays of chars.
public static String repeatString(String what, int howmany) {
char[] pattern = what.toCharArray();
char[] res = new char[howmany * pattern.length];
int length = pattern.length;
for (int i = 0; i < howmany; i++)
System.arraycopy(pattern, 0, res, i * length, length);
return new String(res);
}
To test speed, a similar optimal method using StirngBuilder is like this:
public static String repeatStringSB(String what, int howmany) {
StringBuilder out = new StringBuilder(what.length() * howmany);
for (int i = 0; i < howmany; i++)
out.append(what);
return out.toString();
}
and the code to test it:
public static void main(String... args) {
String res;
long time;
for (int j = 0; j < 1000; j++) {
res = repeatString("123", 100000);
res = repeatStringSB("123", 100000);
}
time = System.nanoTime();
res = repeatString("123", 1000000);
time = System.nanoTime() - time;
System.out.println("elapsed repeatString: " + time);
time = System.nanoTime();
res = repeatStringSB("123", 1000000);
time = System.nanoTime() - time;
System.out.println("elapsed repeatStringSB: " + time);
}
And here the run results from my system:
elapsed repeatString: 6006571
elapsed repeatStringSB: 9064937
Note that the test for loop is to kick in JIT and have optimal results.
a straightforward one-line solution:
requires Java 8
Collections.nCopies( 3, "abc" ).stream().collect( Collectors.joining() );
for the sake of readability and portability:
public String repeat(String str, int count){
if(count <= 0) {return "";}
return new String(new char[count]).replace("\0", str);
}
If you are worried about performance, just use a StringBuilder inside the loop and do a .toString() on exit of the Loop. Heck, write your own Util Class and reuse it. 5 Lines of code max.
I really enjoy this question. There is a lot of knowledge and styles. So I can't leave it without show my rock and roll ;)
{
String string = repeat("1234567890", 4);
System.out.println(string);
System.out.println("=======");
repeatWithoutCopySample(string, 100000);
System.out.println(string);// This take time, try it without printing
System.out.println(string.length());
}
/**
* The core of the task.
*/
#SuppressWarnings("AssignmentToMethodParameter")
public static char[] repeat(char[] sample, int times) {
char[] r = new char[sample.length * times];
while (--times > -1) {
System.arraycopy(sample, 0, r, times * sample.length, sample.length);
}
return r;
}
/**
* Java classic style.
*/
public static String repeat(String sample, int times) {
return new String(repeat(sample.toCharArray(), times));
}
/**
* Java extreme memory style.
*/
#SuppressWarnings("UseSpecificCatch")
public static void repeatWithoutCopySample(String sample, int times) {
try {
Field valueStringField = String.class.getDeclaredField("value");
valueStringField.setAccessible(true);
valueStringField.set(sample, repeat((char[]) valueStringField.get(sample), times));
} catch (Exception ex) {
throw new RuntimeException(ex);
}
}
Do you like it?
public static String repeat(String str, int times) {
int length = str.length();
int size = length * times;
char[] c = new char[size];
for (int i = 0; i < size; i++) {
c[i] = str.charAt(i % length);
}
return new String(c);
}
Simple loop
public static String repeat(String string, int times) {
StringBuilder out = new StringBuilder();
while (times-- > 0) {
out.append(string);
}
return out.toString();
}
Try this out:
public static char[] myABCs = {'a', 'b', 'c'};
public static int numInput;
static Scanner in = new Scanner(System.in);
public static void main(String[] args) {
System.out.print("Enter Number of Times to repeat: ");
numInput = in.nextInt();
repeatArray(numInput);
}
public static int repeatArray(int y) {
for (int a = 0; a < y; a++) {
for (int b = 0; b < myABCs.length; b++) {
System.out.print(myABCs[b]);
}
System.out.print(" ");
}
return y;
}
Using recursion, you can do the following (using ternary operators, one line max):
public static final String repeat(String string, long number) {
return number == 1 ? string : (number % 2 == 0 ? repeat(string + string, number / 2) : string + repeat(string + string, (number - 1) / 2));
}
I know, it's ugly and probably not efficient, but it's one line!
If you only know the length of the output string (and it may be not divisible by the length of the input string), then use this method:
static String repeat(String s, int length) {
return s.length() >= length ? s.substring(0, length) : repeat(s + s, length);
}
Usage demo:
for (int i = 0; i < 50; i++)
System.out.println(repeat("_/‾\\", i));
Don't use with empty s and length > 0, since it's impossible to get the desired result in this case.
Despite your desire not to use loops, I think you should use a loop.
String repeatString(String s, int repetitions)
{
if(repetitions < 0) throw SomeException();
else if(s == null) return null;
StringBuilder stringBuilder = new StringBuilder(s.length() * repetitions);
for(int i = 0; i < repetitions; i++)
stringBuilder.append(s);
return stringBuilder.toString();
}
Your reasons for not using a for loop are not good ones. In response to your criticisms:
Whatever solution you use will almost certainly be longer than this. Using a pre-built function only tucks it under more covers.
Someone reading your code will have to figure out what you're doing in that non-for-loop. Given that a for-loop is the idiomatic way to do this, it would be much easier to figure out if you did it with a for loop.
Yes someone might add something clever, but by avoiding a for loop you are doing something clever. That's like shooting yourself in the foot intentionally to avoid shooting yourself in the foot by accident.
Off-by-one errors are also mind-numbingly easy to catch with a single test. Given that you should be testing your code, an off-by-one error should be easy to fix and catch. And it's worth noting: the code above does not contain an off-by-one error. For loops are equally easy to get right.
So don't reuse variables. That's not the for-loop's fault.
Again, so does whatever solution you use. And as I noted before; a bug hunter will probably be expecting you to do this with a for loop, so they'll have an easier time finding it if you use a for loop.
here is the latest Stringutils.java StringUtils.java
public static String repeat(String str, int repeat) {
// Performance tuned for 2.0 (JDK1.4)
if (str == null) {
return null;
}
if (repeat <= 0) {
return EMPTY;
}
int inputLength = str.length();
if (repeat == 1 || inputLength == 0) {
return str;
}
if (inputLength == 1 && repeat <= PAD_LIMIT) {
return repeat(str.charAt(0), repeat);
}
int outputLength = inputLength * repeat;
switch (inputLength) {
case 1 :
return repeat(str.charAt(0), repeat);
case 2 :
char ch0 = str.charAt(0);
char ch1 = str.charAt(1);
char[] output2 = new char[outputLength];
for (int i = repeat * 2 - 2; i >= 0; i--, i--) {
output2[i] = ch0;
output2[i + 1] = ch1;
}
return new String(output2);
default :
StringBuilder buf = new StringBuilder(outputLength);
for (int i = 0; i < repeat; i++) {
buf.append(str);
}
return buf.toString();
}
}
it doesn't even need to be this big, can be made into this, and can be copied and pasted
into a utility class in your project.
public static String repeat(String str, int num) {
int len = num * str.length();
StringBuilder sb = new StringBuilder(len);
for (int i = 0; i < times; i++) {
sb.append(str);
}
return sb.toString();
}
So e5, I think the best way to do this would be to simply use the above mentioned code,or any of the answers here. but commons lang is just too big if it's a small project
I created a recursive method that do the same thing you want.. feel free to use this...
public String repeat(String str, int count) {
return count > 0 ? repeat(str, count -1) + str: "";
}
i have the same answer on Can I multiply strings in java to repeat sequences?
public static String rep(int a,String k)
{
if(a<=0)
return "";
else
{a--;
return k+rep(a,k);
}
You can use this recursive method for you desired goal.

Substring alternative

So I'm creating a program that will output the first character of a string and then the first character of another string. Then the second character of the first string and the second character of the second string, and so on.
I created what is below, I was just wondering if there is an alternative to this using a loop or something rather than substring
public class Whatever
{
public static void main(String[] args)
{
System.out.println (interleave ("abcdefg", "1234"));
}
public static String interleave(String you, String me)
{
if (you.length() == 0) return me;
else if (me.length() == 0) return you;
return you.substring(0,1) + interleave(me, you.substring(1));
}
}
OUTPUT: a1b2c3d4efg
Well, if you really don't want to use substrings, you can use String's toCharArray() method, then you can use a StringBuilder to append the chars. With this you can loop through each of the array's indices.
Doing so, this would be the outcome:
public static String interleave(String you, String me) {
char[] a = you.toCharArray();
char[] b = me.toCharArray();
StringBuilder out = new StringBuilder();
int maxLength = Math.max(a.length, b.length);
for( int i = 0; i < maxLength; i++ ) {
if( i < a.length ) out.append(a[i]);
if( i < b.length ) out.append(b[i]);
}
return out.toString();
}
Your code is efficient enough as it is, though. This can be an alternative, if you really want to avoid substrings.
This is a loop implementation (not handling null value, just to show the logic):
public static String interleave(String you, String me) {
StringBuilder result = new StringBuilder();
for (int i = 0 ; i < Math.max(you.length(), me.length()) ; i++) {
if (i < you.length()) {
result.append(you.charAt(i)); }
if (i < me.length()) {
result.append(me.charAt(i));
}
}
return result.toString();
}
The solution I am proposing is based on the expected output - In your particular case consider using split method of String since you are interleaving by on character.
So do something like this,
String[] xs = "abcdefg".split("");
String[] ys = "1234".split("");
Now loop over the larger array and ensure interleave ensuring that you perform length checks on the smaller one before accessing.
To implement this as a loop you would have to maintain the position in and keep adding until one finishes then tack the rest on. Any larger sized strings should use a StringBuilder. Something like this (untested):
int i = 0;
String result = "";
while(i <= you.length() && i <= me.length())
{
result += you.charAt(i) + me.charAt(i);
i++;
}
if(i == you.length())
result += me.substring(i);
else
result += you.substring(i);
Improved (in some sense) #BenjaminBoutier answer.
StringBuilder is the most efficient way to concatenate Strings.
public static String interleave(String you, String me) {
StringBuilder result = new StringBuilder();
int min = Math.min(you.length(), me.length());
String longest = you.length() > me.length() ? you : me;
int i = 0;
while (i < min) { // mix characters
result.append(you.charAt(i));
result.append(me.charAt(i));
i++;
}
while (i < longest.length()) { // add the leading characters of longest
result.append(longest.charAt(i));
i++;
}
return result.toString();
}

The fastest method of determining if a string is a palindrome

I need an algorithm that verify with the fastest possible execution time, if a string is a palindrome ( the string can be a proposition with uppercase or lowercase letter, spaces etc.). All of this in Java. I got a sample :
bool isPalindrome(string s) {
int n = s.length();
s = s.toLowerCase();
for (int i = 0; i < (n / 2) + 1; ++i) {
if (s.charAt(i) != s.charAt(n - i - 1)) {
return false;
}
}
return true;
}
I transformed the string in lowercase letter using .toLowerCase() function, but I don't know how much it affects the execution time .
And as well I don't know how to solve the problem with punctuation and spaces between words in a effective way.
I think you can just check for string reverse, not?
StringBuilder sb = new StringBuilder(str);
return str.equals(sb.reverse().toString());
Or, for versions earlier than JDK 1.5:
StringBuffer sb = new StringBuffer(str);
return str.equals(sb.reverse().toString());
This avoids any copying. The functions isBlank and toLowerCase are rather unspecified in your question, so define them the way you want. Just an example:
boolean isBlank(char c) {
return c == ' ' || c == ',';
}
char toLowerCase(char c) {
return Character.toLowerCase(c);
}
Don't worry about the costs of method calls, that's what the JVM excels at.
for (int i = 0, j = s.length() - 1; i < j; ++i, --j) {
while (isBlank(s.charAt(i))) {
i++;
if (i >= j) return true;
}
while (isBlank(s.charAt(j))) {
j--;
if (i >= j) return true;
}
if (toLowerCase(s.charAt(i)) != toLowerCase(s.charAt(j))) return false;
}
return true;
Try to benchmark this... I'm hoping mu solution could be the fastest, but without measuring you never know.
Your solution seems just fine when it comes to effectiveness.
As for your second problem, you can just remove all spaces and dots etc before you start testing:
String stripped = s.toLowerCase().replaceAll("[\\s.,]", "");
int n = stripped.length();
for (int i = 0; i < (n / 2) + 1; ++i) {
if (stripped.charAt(i) != stripped.charAt(n - i - 1)) {
...
Effective is not the same of efficient.
Your answer is effective as long you consider spaces, special characters and so on. Even accents could be problematic.
About efficiency, toLowerCase is O(n) and any regexp parsing will be O(n) also. If you are concerning about that, convert and compare char by char should be the best option.
Here is my try:
public static boolean isPalindrome(String s)
{
int index1 = 0;
int index2 = s.length() -1;
while (index1 < index2)
{
if(s.charAt(index1) != s.charAt(index2))
{
return false;
}
index1 ++;
index2 --;
}
return true;
}
Here's some insight to my way of detecting a palindrome using Java. Feel free to ask question :) Hope I could help in some way....
import java.util.Scanner;
public class Palindrome {
public static void main(String[]args){
if(isReverse()){System.out.println("This is a palindrome.");}
else{System.out.print("This is not a palindrome");}
}
public static boolean isReverse(){
Scanner keyboard = new Scanner(System.in);
System.out.print("Please type something: ");
String line = ((keyboard.nextLine()).toLowerCase()).replaceAll("\\W","");
return (line.equals(new StringBuffer(line).reverse().toString()));
}
}
In normal cases :
StringBuilder sb = new StringBuilder(myString);
String newString=sb.reverse().toString();
return myString.equalsIgnoreCase(newString);
In case of case sensitive use :
StringBuilder sb = new StringBuilder(myString);
String newString=sb.reverse().toString();
return myString.equals(newString);

Java read integer from middle of the string

Is it possible in Java to efficiently read an integer from random position of the string? For instance, I have a
String s = "(34";
if (s.charAt(0) == '(')
{
// How to read a number from position = 1 to the end of the string?
// Of course, I can do something like
String s1 = s.substring(1);
int val = Integer.parseInt(s1);
}
but it dynamically creates a new instance of string and seems to be too slow and performance hitting.
UPDATE
Well, to be precise: I have an array of strings in form "(ddd" where d is a digit. So I do know that a number starts always from pos = 1. How do I efficently read these numbers?
Integer.parseInt(s1.replaceAll("[\\D]", ""))
Answered before the update:
I'm not an expert in regex, but hope this "\\d+" is useful to you. Invoke the below method with pattern: "\\d+".
public static int returnInt(String pattern,String inputString){
Pattern intPattern = Pattern.compile(pattern);
Matcher matcher = intPattern.matcher(inputString);
matcher.find();
String input = matcher.group();
return Integer.parseInt(input);
}
Answered after the update:
String is a final object, you cannot edit it, so if you want to get some digit value from it, you have the 2 ways:
1. Use your code, that will work fine, but if you care about performance, try 2nd way.
2. Divide your string on digits and add them to get the result:
public static void main(String[] args) {
String input = "(123456";
if(input.charAt(0) == '(') {
System.out.println(getDigit(input));
}
}
private static int getDigit(String s) {
int result = 0;
int increase = 10;
for(int i = 1; i < s.length(); i++) {
int digit = Character.getNumericValue(s.charAt(i));
result*=increase;
result += digit;
}
return result;
}
Output:
123456
If you don't want to allocate a new String then you can use the code in this other SO answer:
int charArrayToInt(char[] data, int start, int end) throws NumberFormatException {
int result = 0;
for (int i = start; i < end; i++) {
int digit = ((int)data[i] & 0xF);
if ((digit < 0) || (digit > 9)) throw new NumberFormatException();
result *= 10;
result += digit;
}
return result;
}
You can call it with charArrayToInt(s.toCharArray(), 1, s.length())

Simple way to repeat a string

I'm looking for a simple commons method or operator that allows me to repeat some string n times. I know I could write this using a for loop, but I wish to avoid for loops whenever necessary and a simple direct method should exist somewhere.
String str = "abc";
String repeated = str.repeat(3);
repeated.equals("abcabcabc");
Related to:
repeat string javascript
Create NSString by repeating another string a given number of times
Edited
I try to avoid for loops when they are not completely necessary because:
They add to the number of lines of code even if they are tucked away in another function.
Someone reading my code has to figure out what I am doing in that for loop. Even if it is commented and has meaningful variables names, they still have to make sure it is not doing anything "clever".
Programmers love to put clever things in for loops, even if I write it to "only do what it is intended to do", that does not preclude someone coming along and adding some additional clever "fix".
They are very often easy to get wrong. For loops involving indexes tend to generate off by one bugs.
For loops often reuse the same variables, increasing the chance of really hard to find scoping bugs.
For loops increase the number of places a bug hunter has to look.
Here is the shortest version (Java 1.5+ required):
repeated = new String(new char[n]).replace("\0", s);
Where n is the number of times you want to repeat the string and s is the string to repeat.
No imports or libraries needed.
If you are using Java <= 7, this is as "concise" as it gets:
// create a string made up of n copies of string s
String.format("%0" + n + "d", 0).replace("0", s);
In Java 8 and above there is a more readable way:
// create a string made up of n copies of string s
String.join("", Collections.nCopies(n, s));
Finally, for Java 11 and above, there is a new repeat​(int count) method specifically for this purpose(link)
"abc".repeat(12);
Alternatively, if your project uses java libraries there are more options.
For Apache Commons:
StringUtils.repeat("abc", 12);
For Google Guava:
Strings.repeat("abc", 12);
String::repeat
". ".repeat(7) // Seven period-with-space pairs: . . . . . . .
New in Java 11 is the method String::repeat that does exactly what you asked for:
String str = "abc";
String repeated = str.repeat(3);
repeated.equals("abcabcabc");
Its Javadoc says:
/**
* Returns a string whose value is the concatenation of this
* string repeated {#code count} times.
* <p>
* If this string is empty or count is zero then the empty
* string is returned.
*
* #param count number of times to repeat
*
* #return A string composed of this string repeated
* {#code count} times or the empty string if this
* string is empty or count is zero
*
* #throws IllegalArgumentException if the {#code count} is
* negative.
*
* #since 11
*/
Commons Lang StringUtils.repeat()
Usage:
String str = "abc";
String repeated = StringUtils.repeat(str, 3);
repeated.equals("abcabcabc");
Java 8's String.join provides a tidy way to do this in conjunction with Collections.nCopies:
// say hello 100 times
System.out.println(String.join("", Collections.nCopies(100, "hello")));
Here's a way to do it using only standard String functions and no explicit loops:
// create a string made up of n copies of s
repeated = String.format(String.format("%%%ds", n), " ").replace(" ",s);
If you're like me and want to use Google Guava and not Apache Commons. You can use the repeat method in the Guava Strings class.
Strings.repeat("-", 60);
With java-8, you can also use Stream.generate.
import static java.util.stream.Collectors.joining;
...
String repeated = Stream.generate(() -> "abc").limit(3).collect(joining()); //"abcabcabc"
and you can wrap it in a simple utility method if needed:
public static String repeat(String str, int times) {
return Stream.generate(() -> str).limit(times).collect(joining());
}
So you want to avoid loops?
Here you have it:
public static String repeat(String s, int times) {
if (times <= 0) return "";
else return s + repeat(s, times-1);
}
(of course I know this is ugly and inefficient, but it doesn't have loops :-p)
You want it simpler and prettier? use jython:
s * 3
Edit: let's optimize it a little bit :-D
public static String repeat(String s, int times) {
if (times <= 0) return "";
else if (times % 2 == 0) return repeat(s+s, times/2);
else return s + repeat(s+s, times/2);
}
Edit2: I've done a quick and dirty benchmark for the 4 main alternatives, but I don't have time to run it several times to get the means and plot the times for several inputs... So here's the code if anybody wants to try it:
public class Repeat {
public static void main(String[] args) {
int n = Integer.parseInt(args[0]);
String s = args[1];
int l = s.length();
long start, end;
start = System.currentTimeMillis();
for (int i = 0; i < n; i++) {
if(repeatLog2(s,i).length()!=i*l) throw new RuntimeException();
}
end = System.currentTimeMillis();
System.out.println("RecLog2Concat: " + (end-start) + "ms");
start = System.currentTimeMillis();
for (int i = 0; i < n; i++) {
if(repeatR(s,i).length()!=i*l) throw new RuntimeException();
}
end = System.currentTimeMillis();
System.out.println("RecLinConcat: " + (end-start) + "ms");
start = System.currentTimeMillis();
for (int i = 0; i < n; i++) {
if(repeatIc(s,i).length()!=i*l) throw new RuntimeException();
}
end = System.currentTimeMillis();
System.out.println("IterConcat: " + (end-start) + "ms");
start = System.currentTimeMillis();
for (int i = 0; i < n; i++) {
if(repeatSb(s,i).length()!=i*l) throw new RuntimeException();
}
end = System.currentTimeMillis();
System.out.println("IterStrB: " + (end-start) + "ms");
}
public static String repeatLog2(String s, int times) {
if (times <= 0) {
return "";
}
else if (times % 2 == 0) {
return repeatLog2(s+s, times/2);
}
else {
return s + repeatLog2(s+s, times/2);
}
}
public static String repeatR(String s, int times) {
if (times <= 0) {
return "";
}
else {
return s + repeatR(s, times-1);
}
}
public static String repeatIc(String s, int times) {
String tmp = "";
for (int i = 0; i < times; i++) {
tmp += s;
}
return tmp;
}
public static String repeatSb(String s, int n) {
final StringBuilder sb = new StringBuilder();
for(int i = 0; i < n; i++) {
sb.append(s);
}
return sb.toString();
}
}
It takes 2 arguments, the first is the number of iterations (each function run with repeat times arg from 1..n) and the second is the string to repeat.
So far, a quick inspection of the times running with different inputs leaves the ranking something like this (better to worse):
Iterative StringBuilder append (1x).
Recursive concatenation log2 invocations (~3x).
Recursive concatenation linear invocations (~30x).
Iterative concatenation linear (~45x).
I wouldn't ever guessed that the recursive function was faster than the for loop :-o
Have fun(ctional xD).
This contains less characters than your question
public static String repeat(String s, int n) {
if(s == null) {
return null;
}
final StringBuilder sb = new StringBuilder(s.length() * n);
for(int i = 0; i < n; i++) {
sb.append(s);
}
return sb.toString();
}
based on fortran's answer, this is a recusive version that uses a StringBuilder:
public static void repeat(StringBuilder stringBuilder, String s, int times) {
if (times > 0) {
repeat(stringBuilder.append(s), s, times - 1);
}
}
public static String repeat(String s, int times) {
StringBuilder stringBuilder = new StringBuilder(s.length() * times);
repeat(stringBuilder, s, times);
return stringBuilder.toString();
}
using Dollar is simple as typing:
#Test
public void repeatString() {
String string = "abc";
assertThat($(string).repeat(3).toString(), is("abcabcabc"));
}
PS: repeat works also for array, List, Set, etc
I wanted a function to create a comma-delimited list of question marks for JDBC purposes, and found this post. So, I decided to take two variants and see which one performed better. After 1 million iterations, the garden-variety StringBuilder took 2 seconds (fun1), and the cryptic supposedly more optimal version (fun2) took 30 seconds. What's the point of being cryptic again?
private static String fun1(int size) {
StringBuilder sb = new StringBuilder(size * 2);
for (int i = 0; i < size; i++) {
sb.append(",?");
}
return sb.substring(1);
}
private static String fun2(int size) {
return new String(new char[size]).replaceAll("\0", ",?").substring(1);
}
OOP Solution
Nearly every answer proposes a static function as a solution, but thinking Object-Oriented (for reusability-purposes and clarity) I came up with a Solution via Delegation through the CharSequence-Interface (which also opens up usability on mutable CharSequence-Classes).
The following Class can be used either with or without Separator-String/CharSequence and each call to "toString()" builds the final repeated String.
The Input/Separator are not only limited to String-Class, but can be every Class which implements CharSequence (e.g. StringBuilder, StringBuffer, etc)!
Source-Code:
/**
* Helper-Class for Repeating Strings and other CharSequence-Implementations
* #author Maciej Schuttkowski
*/
public class RepeatingCharSequence implements CharSequence {
final int count;
CharSequence internalCharSeq = "";
CharSequence separator = "";
/**
* CONSTRUCTOR - RepeatingCharSequence
* #param input CharSequence to repeat
* #param count Repeat-Count
*/
public RepeatingCharSequence(CharSequence input, int count) {
if(count < 0)
throw new IllegalArgumentException("Can not repeat String \""+input+"\" less than 0 times! count="+count);
if(count > 0)
internalCharSeq = input;
this.count = count;
}
/**
* CONSTRUCTOR - Strings.RepeatingCharSequence
* #param input CharSequence to repeat
* #param count Repeat-Count
* #param separator Separator-Sequence to use
*/
public RepeatingCharSequence(CharSequence input, int count, CharSequence separator) {
this(input, count);
this.separator = separator;
}
#Override
public CharSequence subSequence(int start, int end) {
checkBounds(start);
checkBounds(end);
int subLen = end - start;
if (subLen < 0) {
throw new IndexOutOfBoundsException("Illegal subSequence-Length: "+subLen);
}
return (start == 0 && end == length()) ? this
: toString().substring(start, subLen);
}
#Override
public int length() {
//We return the total length of our CharSequences with the separator 1 time less than amount of repeats:
return count < 1 ? 0
: ( (internalCharSeq.length()*count) + (separator.length()*(count-1)));
}
#Override
public char charAt(int index) {
final int internalIndex = internalIndex(index);
//Delegate to Separator-CharSequence or Input-CharSequence depending on internal index:
if(internalIndex > internalCharSeq.length()-1) {
return separator.charAt(internalIndex-internalCharSeq.length());
}
return internalCharSeq.charAt(internalIndex);
}
#Override
public String toString() {
return count < 1 ? ""
: new StringBuilder(this).toString();
}
private void checkBounds(int index) {
if(index < 0 || index >= length())
throw new IndexOutOfBoundsException("Index out of Bounds: "+index);
}
private int internalIndex(int index) {
// We need to add 1 Separator-Length to total length before dividing,
// as we subtracted one Separator-Length in "length()"
return index % ((length()+separator.length())/count);
}
}
Usage-Example:
public static void main(String[] args) {
//String input = "12345";
//StringBuffer input = new StringBuffer("12345");
StringBuilder input = new StringBuilder("123");
//String separator = "<=>";
StringBuilder separator = new StringBuilder("<=");//.append('>');
int repeatCount = 2;
CharSequence repSeq = new RepeatingCharSequence(input, repeatCount, separator);
String repStr = repSeq.toString();
System.out.println("Repeat="+repeatCount+"\tSeparator="+separator+"\tInput="+input+"\tLength="+input.length());
System.out.println("CharSeq:\tLength="+repSeq.length()+"\tVal="+repSeq);
System.out.println("String :\tLength="+repStr.length()+"\tVal="+repStr);
//Here comes the Magic with a StringBuilder as Input, as you can append to the String-Builder
//and at the same Time your Repeating-Sequence's toString()-Method returns the updated String :)
input.append("ff");
System.out.println(repSeq);
//Same can be done with the Separator:
separator.append("===").append('>');
System.out.println(repSeq);
}
Example-Output:
Repeat=2 Separator=<= Input=123 Length=3
CharSeq: Length=8 Val=123<=123
String : Length=8 Val=123<=123
123ff<=123ff
123ff<====>123ff
using only JRE classes (System.arraycopy) and trying to minimize the number of temp objects you can write something like:
public static String repeat(String toRepeat, int times) {
if (toRepeat == null) {
toRepeat = "";
}
if (times < 0) {
times = 0;
}
final int length = toRepeat.length();
final int total = length * times;
final char[] src = toRepeat.toCharArray();
char[] dst = new char[total];
for (int i = 0; i < total; i += length) {
System.arraycopy(src, 0, dst, i, length);
}
return String.copyValueOf(dst);
}
EDIT
and without loops you can try with:
public static String repeat2(String toRepeat, int times) {
if (toRepeat == null) {
toRepeat = "";
}
if (times < 0) {
times = 0;
}
String[] copies = new String[times];
Arrays.fill(copies, toRepeat);
return Arrays.toString(copies).
replace("[", "").
replace("]", "").
replaceAll(", ", "");
}
EDIT 2
using Collections is even shorter:
public static String repeat3(String toRepeat, int times) {
return Collections.nCopies(times, toRepeat).
toString().
replace("[", "").
replace("]", "").
replaceAll(", ", "");
}
however I still like the first version.
Not the shortest, but (i think) the fastest way is to use the StringBuilder:
/**
* Repeat a String as many times you need.
*
* #param i - Number of Repeating the String.
* #param s - The String wich you want repeated.
* #return The string n - times.
*/
public static String repeate(int i, String s) {
StringBuilder sb = new StringBuilder();
for (int j = 0; j < i; j++)
sb.append(s);
return sb.toString();
}
If speed is your concern, then you should use as less memory copying as possible. Thus it is required to work with arrays of chars.
public static String repeatString(String what, int howmany) {
char[] pattern = what.toCharArray();
char[] res = new char[howmany * pattern.length];
int length = pattern.length;
for (int i = 0; i < howmany; i++)
System.arraycopy(pattern, 0, res, i * length, length);
return new String(res);
}
To test speed, a similar optimal method using StirngBuilder is like this:
public static String repeatStringSB(String what, int howmany) {
StringBuilder out = new StringBuilder(what.length() * howmany);
for (int i = 0; i < howmany; i++)
out.append(what);
return out.toString();
}
and the code to test it:
public static void main(String... args) {
String res;
long time;
for (int j = 0; j < 1000; j++) {
res = repeatString("123", 100000);
res = repeatStringSB("123", 100000);
}
time = System.nanoTime();
res = repeatString("123", 1000000);
time = System.nanoTime() - time;
System.out.println("elapsed repeatString: " + time);
time = System.nanoTime();
res = repeatStringSB("123", 1000000);
time = System.nanoTime() - time;
System.out.println("elapsed repeatStringSB: " + time);
}
And here the run results from my system:
elapsed repeatString: 6006571
elapsed repeatStringSB: 9064937
Note that the test for loop is to kick in JIT and have optimal results.
a straightforward one-line solution:
requires Java 8
Collections.nCopies( 3, "abc" ).stream().collect( Collectors.joining() );
for the sake of readability and portability:
public String repeat(String str, int count){
if(count <= 0) {return "";}
return new String(new char[count]).replace("\0", str);
}
If you are worried about performance, just use a StringBuilder inside the loop and do a .toString() on exit of the Loop. Heck, write your own Util Class and reuse it. 5 Lines of code max.
I really enjoy this question. There is a lot of knowledge and styles. So I can't leave it without show my rock and roll ;)
{
String string = repeat("1234567890", 4);
System.out.println(string);
System.out.println("=======");
repeatWithoutCopySample(string, 100000);
System.out.println(string);// This take time, try it without printing
System.out.println(string.length());
}
/**
* The core of the task.
*/
#SuppressWarnings("AssignmentToMethodParameter")
public static char[] repeat(char[] sample, int times) {
char[] r = new char[sample.length * times];
while (--times > -1) {
System.arraycopy(sample, 0, r, times * sample.length, sample.length);
}
return r;
}
/**
* Java classic style.
*/
public static String repeat(String sample, int times) {
return new String(repeat(sample.toCharArray(), times));
}
/**
* Java extreme memory style.
*/
#SuppressWarnings("UseSpecificCatch")
public static void repeatWithoutCopySample(String sample, int times) {
try {
Field valueStringField = String.class.getDeclaredField("value");
valueStringField.setAccessible(true);
valueStringField.set(sample, repeat((char[]) valueStringField.get(sample), times));
} catch (Exception ex) {
throw new RuntimeException(ex);
}
}
Do you like it?
public static String repeat(String str, int times) {
int length = str.length();
int size = length * times;
char[] c = new char[size];
for (int i = 0; i < size; i++) {
c[i] = str.charAt(i % length);
}
return new String(c);
}
Simple loop
public static String repeat(String string, int times) {
StringBuilder out = new StringBuilder();
while (times-- > 0) {
out.append(string);
}
return out.toString();
}
Try this out:
public static char[] myABCs = {'a', 'b', 'c'};
public static int numInput;
static Scanner in = new Scanner(System.in);
public static void main(String[] args) {
System.out.print("Enter Number of Times to repeat: ");
numInput = in.nextInt();
repeatArray(numInput);
}
public static int repeatArray(int y) {
for (int a = 0; a < y; a++) {
for (int b = 0; b < myABCs.length; b++) {
System.out.print(myABCs[b]);
}
System.out.print(" ");
}
return y;
}
Using recursion, you can do the following (using ternary operators, one line max):
public static final String repeat(String string, long number) {
return number == 1 ? string : (number % 2 == 0 ? repeat(string + string, number / 2) : string + repeat(string + string, (number - 1) / 2));
}
I know, it's ugly and probably not efficient, but it's one line!
If you only know the length of the output string (and it may be not divisible by the length of the input string), then use this method:
static String repeat(String s, int length) {
return s.length() >= length ? s.substring(0, length) : repeat(s + s, length);
}
Usage demo:
for (int i = 0; i < 50; i++)
System.out.println(repeat("_/‾\\", i));
Don't use with empty s and length > 0, since it's impossible to get the desired result in this case.
Despite your desire not to use loops, I think you should use a loop.
String repeatString(String s, int repetitions)
{
if(repetitions < 0) throw SomeException();
else if(s == null) return null;
StringBuilder stringBuilder = new StringBuilder(s.length() * repetitions);
for(int i = 0; i < repetitions; i++)
stringBuilder.append(s);
return stringBuilder.toString();
}
Your reasons for not using a for loop are not good ones. In response to your criticisms:
Whatever solution you use will almost certainly be longer than this. Using a pre-built function only tucks it under more covers.
Someone reading your code will have to figure out what you're doing in that non-for-loop. Given that a for-loop is the idiomatic way to do this, it would be much easier to figure out if you did it with a for loop.
Yes someone might add something clever, but by avoiding a for loop you are doing something clever. That's like shooting yourself in the foot intentionally to avoid shooting yourself in the foot by accident.
Off-by-one errors are also mind-numbingly easy to catch with a single test. Given that you should be testing your code, an off-by-one error should be easy to fix and catch. And it's worth noting: the code above does not contain an off-by-one error. For loops are equally easy to get right.
So don't reuse variables. That's not the for-loop's fault.
Again, so does whatever solution you use. And as I noted before; a bug hunter will probably be expecting you to do this with a for loop, so they'll have an easier time finding it if you use a for loop.
here is the latest Stringutils.java StringUtils.java
public static String repeat(String str, int repeat) {
// Performance tuned for 2.0 (JDK1.4)
if (str == null) {
return null;
}
if (repeat <= 0) {
return EMPTY;
}
int inputLength = str.length();
if (repeat == 1 || inputLength == 0) {
return str;
}
if (inputLength == 1 && repeat <= PAD_LIMIT) {
return repeat(str.charAt(0), repeat);
}
int outputLength = inputLength * repeat;
switch (inputLength) {
case 1 :
return repeat(str.charAt(0), repeat);
case 2 :
char ch0 = str.charAt(0);
char ch1 = str.charAt(1);
char[] output2 = new char[outputLength];
for (int i = repeat * 2 - 2; i >= 0; i--, i--) {
output2[i] = ch0;
output2[i + 1] = ch1;
}
return new String(output2);
default :
StringBuilder buf = new StringBuilder(outputLength);
for (int i = 0; i < repeat; i++) {
buf.append(str);
}
return buf.toString();
}
}
it doesn't even need to be this big, can be made into this, and can be copied and pasted
into a utility class in your project.
public static String repeat(String str, int num) {
int len = num * str.length();
StringBuilder sb = new StringBuilder(len);
for (int i = 0; i < times; i++) {
sb.append(str);
}
return sb.toString();
}
So e5, I think the best way to do this would be to simply use the above mentioned code,or any of the answers here. but commons lang is just too big if it's a small project
I created a recursive method that do the same thing you want.. feel free to use this...
public String repeat(String str, int count) {
return count > 0 ? repeat(str, count -1) + str: "";
}
i have the same answer on Can I multiply strings in java to repeat sequences?
public static String rep(int a,String k)
{
if(a<=0)
return "";
else
{a--;
return k+rep(a,k);
}
You can use this recursive method for you desired goal.

Categories

Resources