I'm utterly boggled as to why charAt() works in some scenarios but not others. I am doing exercises while learning Java and one of them was to take a string, and return it in reverse order.
My working code:
public String reverseString(String tempStr){
int initialindex = tempStr.length()-1;
int reverseindex = 0;
char tmp;
char[] array = new char[tempStr.length()];
for(int tempchar : array){
tmp = tempStr.charAt(initialindex);
array[reverseindex] = tmp;
initialindex--;
reverseindex++;
}
String returnstr = new String(array);
return returnstr;
}
The problem I ran into is using the following for statement prints gibberish:
for(int tempchar : array){
array[reverseindex] = tempStr.charAt(initialindex);
initialindex--;
reverseindex++;
}
There were perhaps a dozen different variants of using while loops, standard for loops and a few other versions of code that were ugly and didn't work. Why did my making a char tmp field, putting the inspected characrer in said field, and then using said field to enter the data into an array work?
Also, why am I unable to just return the string using return array.toString();?
Edit: I'm using the latest Eclipse I downloaded today, switched from netbeans.
I copied your code into my editor and it performed fine using either version, with tmp field or without. You must have made some other error using the other method.
Java doesn't support pretty .toString() for arrays; any object which does not override toString will produce the hashCode of the object rather than the contents/fields of the object, and arrays are no exception here. Whilst it might seem sensible for character arrays, the same operation on an int array would produce nonsense; See the difference between Arrays.toString() and String.valueOf(array). In this case, you probably want to use the String.valueOf method.
The array.toString() return string representation of the object. You need to use char[] constructor of String new String(array) to create String from the char[].
As a hint to get you started: if you want to convert a char array into a String use the String constructor that takes a char array.
Update: I see you already did that in your edit. Does it work as expected now?
Your loop looks a little bit weird since you never use your loop variable. you could try this:
char[] initialArray = initialStr.toCharArray();
char[] array = new char[tempStr.length()];
for(int srcIndex = 0, destIndex = array.length-1; destIndex >= 0; srcIndex++, destIndex--) {
array[destIndex] = initialArray[srcIndex];
}
public String reverse(String str)
{
if(str == null)
{
return null;
}
byte[] byteArray= str.getBytes();
int arrayLastIndex = byteArray.length -1 ;
for(int i=0 ; i < byteArray.lenght/2: i++)
{
byte temp = byteArray[i];
byteArray[i] = byteArray[arrayLastIndex -i ]
byteArray[arrayLastIndex - i] = temp;
}
return new String(byteArray);
}
Related
i am trying to sort a string in the alphabetical order, however i am facing an error in the line :
sb.charAt(j)=sb.charAt(j+1);
where the compiler shows an error as expected variable; found value
the rest of the code is as follows :
import java.util.Scanner;
class a
{
public static void main(String[] agrs)
{
Scanner sc = new Scanner(System.in);
String s = sc.next();
StringBuffer sb = new StringBuffer();
sb.append(s);
for(int i = 0; i< s.length(); i++)
{
for(int j = 0; j<s.length(); j++)
{
if(s.charAt(j)>s.charAt(j+1)){
char temp = s.charAt(j);
sb.charAt(j)=sb.charAt(j+1);
sb.charAt(j+1)=temp;
}
}
}}}
kindly help me out as i'm a beginner and i cannot figure out why this issue is occurring , thank you .
This looks like a homework assignment where the goal is to sort the characters of a text being entered, so if you enter gfedbca the result should be abcdefg.
You already got a comment telling you what the problem is: StringBuffer#charAt() is not returning a reference to StringBuffer's internal array that you can change the value of. Dependent on the actual assignment you can call StringBuffers setCharAt method or you can go another approach by converting the text to sort to a char array and do the sorting in there. There are actually helper-classes in the JVM, that do that for you, have a look e.g. at the class java.util.Arrays
As already answered by many, the issue is in charAt(index) you are using, as this returns the character at the given index rather than setting a char at the index position.
My answer is to divert your approach of sorting. For simpler solutions, where smaller data sets (like your problem) are used, you should use the predefined sorting algorithms, like Insertion Sort
You may get help for the algo from here: http://www.geeksforgeeks.org/insertion-sort/
StringBuffer's charAt returns just the value of the char at the index, if you want to swap two chars you need to use setter for that, so you possible want to do somtehing like:
for(int j = 0; j < s.length() - 1; j++) {
if(s.charAt(j) > s.charAt(j + 1)) {
char temp = s.charAt(j);
sb.setCharAt(j, sb.charAt(j + 1));
sb.setCharAt(j + 1, temp);
}
}
This method can only return values and can not set values, I guess you might want to use this method:
setCharAt()
It can meet your requirement
I am trying to convert a string to an array then back to a string again. I am trying to achieve this in C# but as i have not done C# in a while i am having issues. I created the following code in Java and it works fine:
String sHtml = "test1\r\ntest2\r\ntest3\r\ntest4\r\ntes5t\r\ntest6\r\ntest7\r\ntest8\r\ntest9\r\ntest10\r\ntest11\r\ntest12\r\ntest13\r\ntes14t\r\n";
int temp = 0;
List<String> emailText = new ArrayList<String>();
for(int x = 0; x<sHtml.length();x++){
if(sHtml.charAt(x)=='\n'){
emailText.add(sHtml.substring(temp, x));
temp = x;
}
}
String testingString="";
for(String words:emailText){
//System.out.println(words);
testingString+=words;
}
System.out.println(testingString);
This works fine in Java. The following code is what i have for C#:
int temp = 0;
List<string> emailText = new List<string>();
for (int x = 0; x < sHtml.Length; x++)
{
if (sHtml[x].Equals("\\n"))
{
emailText.Add(sHtml.Substring(temp, x));
temp = x;
}
else
{
}
}
string testingString = "";
//sHtml = string.Join("\r\n", emailText.ToArray());
foreach (String word in emailText)
{
testingString += word;
}
Console.WriteLine(testingString);
The java code outputs fine but i am getting no output from the C# code. I have a feeling i am missing something small from the C# code but i am not sure what, Can someone please help?
Thanks in advance
You don't get output in C# because you don't output anything :-) You omitted the Java System.out.println statement without adding the C# equivalent:
Console.WriteLine(testingString);
BTW: Once you're replacing your Java code by C# code, you can also make use of the .NET framework's features (as others already mentioned). This way you can reduce your program to one line:
Console.WriteLine(string.Join(string.Empty, sHtml.Split('\n')));
Try this: although i would recommend using a string builder for larger strings as they're immutable.
string yourString = "this,is,a,example,string";
string newString = "";
string[] array = yourString.Split(',');
foreach (string s in array)
{
newString += s;
}
Console.WriteLine(newString);
Why don't you use this to split the string:
string[] List = sHtml.split("\\n");
And this to do something with the arraylist of strings to do something:
for (String s in List){
//Do something with each separate String s
}
Why not use split and join?
var arr = str.Split('\n');
var newStr = string.Join("", arr);
Your 'for' loop has 2 mistakes - you should keep the character '\n' and Java 'substring' doesn't have the same second parameter that .NET 'Substring' has, so you need to adjust that:
for (int x = 0; x < sHtml.Length;x++)
{
if (sHtml[x] == '\n')
{
emailText.Add(sHtml.Substring(temp, x - temp));
temp = x;
}
}
I have been working on the Project Euler problem 4. I am new to java, and believe I have found the answer (906609 = 993 * 913, by using Excel!).
When I print the line commented out, I can that my string manipulations have worked. I've researched a few ways to compare strings in case I had not understoof something, but this routine doesn't give me a result.
Please help me identify why it is not printing the answer?
James
public class pall{
public static void main(String[] args){
int i;
int j;
long k;
String stringProd;
for(i=994;i>992; i--){
for (j=914;j>912; j--){
k=(i*j);
stringProd=String.valueOf(k);
int len=stringProd.length();
char[] forwards=new char[len];
char[] back = new char[len];
for(int l=0; l<len; l++){
forwards[l]=stringProd.charAt(l);
}
for(int m=0; m<len;m++){
back[m]=forwards[len-1-m];
}
//System.out.println(forwards);
//System.out.println(back);
if(forwards.toString().equals(back.toString())){
System.out.println(k);}
}
}
}
}
You are comparing the string representation of your array. toString() doesn't give you what you think. For example, the below code makes it clear:
char[] arr1 = {'a', 'b'};
char[] arr2 = {'a', 'b'};
System.out.println(arr1.toString() + " : " + arr2.toString());
this code prints:
[C#16f0472 : [C#18d107f
So, the string representation of both the arrays are different, even though the contents are equal. This is because arrays don't override toString() method. It inherits the Object#toString() method.
The toString method for class Object returns a string consisting of
the name of the class of which the object is an instance, the at-sign
character #, and the unsigned hexadecimal representation of the hash
code of the object. In other words, this method returns a string equal
to the value of:
getClass().getName() + '#' + Integer.toHexString(hashCode())
So, in the above output, [C is the output of char[].class.getName(), and 18d107f is the hashcode.
You can't also compare the arrays using forward.equals(back), as arrays in Java don't override equals() or hashCode() either. Any options? Yes, for comparing arrays you can use Arrays#equals(char[], char[]) method:
if (Arrays.equals(forward, back)) {
System.out.println(k);
}
Also, to get your char arrays, you don't need those loops. You can use String#toCharArray() method. And also to get the reverse of the String, you can wrap the string in a StringBuilder instance, and use it's reverse() method:
char[] forwards = stringProd.toCharArray();
char[] back = new StringBuilder(stringPod).reverse().toString().toCharArray();
And now that you have found out an easy way to reverse a string, then how about using String#equals() method directly, and resist creating those character arrays?
String stringPod = String.valueOf(k);
String reverseStringPod = new StringBuilder(stringPod).reverse().toString()
if (stringPod.equals(reverseStringPod)) {
System.out.println(k);
}
Finally, since it is about project euler, which is about speed and mostly mathematics. You should consider avoiding String utilities, and do it with general division and modulus arithmetic, to get each individual digits, from beginning and end, and compare them.
To convert a string to char[] use
char[] forward = stringProd.toCharArray();
To convert a char[] to String, use String(char[]) constructor:
String backStr = new String(back); // Not the same as back.toString()
However, this is not the most performant solution, for several reasons:
You do not need to construct a back array to check if a string is a palindrome - you can walk the string from both ends, comparing the characters as you go, until you either find a difference or your indexes meet in the middle.
Rather than constructing a new array in a loop, you could reuse the same array - in case you do want to continue with an array, you could allocate it once for the maximum length of the product k, and use it in all iterations of your loop.
You do not need to convert a number to string in order to check if it is a palindrome - you can get its digits by repeatedly taking the remainder of division by ten, and then dividing by ten to go to the next digit.
Here is an illustration of the last point:
boolean isPalindrome(int n) {
int[] digits = new int[10];
if (n < 0) n = -n;
int len = 0;
while (n != 0) {
digits[len++] = n % 10;
n /= 10;
}
// Start two indexes from the opposite sides
int left = 0, right = len-1;
// Loop until they meet in the middle
while (left < right) {
if (digits[left++] != digits[right--]) {
return false;
}
}
return true;
}
I have a piece of code that needs to be optimized.
for (int i = 0; i < wordLength; i++) {
for (int c = 0; c < alphabetLength; c++) {
if (alphabet[c] != x.word.charAt(i)) {
String res = WordList.Contains(x.word.substring(0,i) +
alphabet[c] +
x.word.substring(i+1));
if (res != null && WordList.MarkAsUsedIfUnused(res)) {
WordRec wr = new WordRec(res, x);
if (IsGoal(res)) return wr;
q.Put(wr);
}
}
}
Words are represented by string. The problem is that the code on line 4-6 creates to many string objects, because strings are immutable.
Which data structure should I change my word representation to, if I want to get faster code ? I have tried to change it to char[], but then I have problem with getting the following code work:
x.word.substring(0,i)
How to get subarray from a char[] ? And how to concatenate the char and char[] on line 4.6 ?
Is there any other suitable and mutable datastrucure that I can use ? I have thought of stringbuffer but can't find suitable operations on stringbuffers.
This function generates, given a specific word, all the word that differs by one character.
WordRec is just a class with a string representing a word, and a pointer to the "father" of that word.
Thanks in advance
You can reduce number of objects by using this approach:
StringBuilder tmp = new StringBuilder(wordLength);
tmp.append(x.word);
for (int i=...) {
for (int c=...) {
if (...) {
char old = tmp.charAt(i);
tmp.setCharAt(i, alphabet[c]);
String res = tmp.toString();
tmp.setCharAt(i, old);
...
}
}
}
This question already has answers here:
Simple way to repeat a string
(32 answers)
Closed 4 years ago.
I did check the other questions; this question has its focus on solving this particular question the most efficient way.
Sometimes you want to create a new string with a specified length, and with a default character filling the entire string.
ie, it would be cool if you could do new String(10, '*') and create a new String from there, with a length of 10 characters all having a *.
Because such a constructor does not exist, and you cannot extend from String, you have either to create a wrapper class or a method to do this for you.
At this moment I am using this:
protected String getStringWithLengthAndFilledWithCharacter(int length, char charToFill) {
char[] array = new char[length];
int pos = 0;
while (pos < length) {
array[pos] = charToFill;
pos++;
}
return new String(array);
}
It still lacks any checking (ie, when length is 0 it will not work). I am constructing the array first because I believe it is faster than using string concatination or using a StringBuffer to do so.
Anyone else has a better sollution?
Apache Commons Lang (probably useful enough to be on the classpath of any non-trivial project) has StringUtils.repeat():
String filled = StringUtils.repeat("*", 10);
Easy!
Simply use the StringUtils class from apache commons lang project. You have a leftPad method:
StringUtils.leftPad("foobar", 10, '*'); // Returns "****foobar"
No need to do the loop, and using just standard Java library classes:
protected String getStringWithLengthAndFilledWithCharacter(int length, char charToFill) {
if (length > 0) {
char[] array = new char[length];
Arrays.fill(array, charToFill);
return new String(array);
}
return "";
}
As you can see, I also added suitable code for the length == 0 case.
Some possible solutions.
This creates a String with length-times '0' filled and replaces then the '0' with the charToFill (old school).
String s = String.format("%0" + length + "d", 0).replace('0', charToFill);
This creates a List containing length-times Strings with charToFill and then joining the List into a String.
String s = String.join("", Collections.nCopies(length, String.valueOf(charToFill)));
This creates a unlimited java8 Stream with Strings with charToFill, limits the output to length and collects the results with a String joiner (new school).
String s = Stream.generate(() -> String.valueOf(charToFill)).limit(length).collect(Collectors.joining());
In Java 11, you have repeat:
String s = " ";
s = s.repeat(1);
(Although at the time of writing still subject to change)
char[] chars = new char[10];
Arrays.fill(chars, '*');
String text = new String(chars);
To improve performance you could have a single predefined sting if you know the max length like:
String template = "####################################";
And then simply perform a substring once you know the length.
Solution using Google Guava
String filled = Strings.repeat("*", 10);
public static String fillString(int count,char c) {
StringBuilder sb = new StringBuilder( count );
for( int i=0; i<count; i++ ) {
sb.append( c );
}
return sb.toString();
}
What is wrong?
using Dollar is simple:
String filled = $("=").repeat(10).toString(); // produces "=========="
Solution using Google Guava, since I prefer it to Apache Commons-Lang:
/**
* Returns a String with exactly the given length composed entirely of
* the given character.
* #param length the length of the returned string
* #param c the character to fill the String with
*/
public static String stringOfLength(final int length, final char c)
{
return Strings.padEnd("", length, c);
}
The above is fine. Do you mind if I ask you a question - Is this causing you a problem? It seams to me you are optimizing before you know if you need to.
Now for my over engineered solution. In many (thou not all) cases you can use CharSequence instead of a String.
public class OneCharSequence implements CharSequence {
private final char value;
private final int length;
public OneCharSequence(final char value, final int length) {
this.value = value;
this.length = length;
}
public char charAt(int index) {
if(index < length) return value;
throw new IndexOutOfBoundsException();
}
public int length() {
return length;
}
public CharSequence subSequence(int start, int end) {
return new OneCharSequence(value, (end-start));
}
public String toString() {
char[] array = new char[length];
Arrays.fill(array, value);
return new String(array);
}
}
One extra note: it seems that all public ways of creating a new String instance involves necessarily the copy of whatever buffer you are working with, be it a char[], a StringBuffer or a StringBuilder. From the String javadoc (and is repeated in the respective toString methods from the other classes):
The contents of the character array are copied; subsequent modification of
the character array does not affect
the newly created string.
So you'll end up having a possibly big memory copy operation after the "fast filling" of the array. The only solution that may avoid this issue is the one from #mlk, if you can manage working directly with the proposed CharSequence implementation (what may be the case).
PS: I would post this as a comment but I don't have enough reputation to do that yet.
Try this Using the substring(int start, int end); method
String myLongString = "abcdefghij";
if (myLongString .length() >= 10)
String shortStr = myLongString.substring(0, 5)+ "...";
this will return abcde.
Mi solution :
pw = "1321";
if (pw.length() < 16){
for(int x = pw.length() ; x < 16 ; x++){
pw += "*";
}
}
The output :
1321************
Try this jobber
String stringy =null;
byte[] buffer = new byte[100000];
for (int i = 0; i < buffer.length; i++) {
buffer[i] =0;
}
stringy =StringUtils.toAsciiString(buffer);