This is my code
public static String change(String word, char gone, char here) {
char[] chars = word.toCharArray();
for (char c : chars) {
if (c == gone) {
c = here;
}
}
return new String(chars);
}
and this how i call it:
System.out.println(change("supper", 'p', 'o'));
the result is supper I was trying to find explanation to what is going on ...
the chars variable is a variable that is refers to an array object, and which contains the characters of the String object word. then the only explanation that I thought about is that in the for statement, java actually copies the chars array.Is that correct?
some users said that there is a warning in my code,
but here you go, no warnings
c = here;
Updates the value of the character, not the array. If you used an editor it would tell you that the assigned value is not used.
Editors like IntelliJ above are free, so you have no excuse.
The c variable is just a copied reference to the array element.
The reason for this is that the enhanced for loop uses an Iterator and in order to get the next element, it invokes the Iterator.next() method, which gives a copy to the original collection element.
In order to make it work, you have to directly set the new value into the array:
public static String change(String word, char gone, char here) {
char[] chars = word.toCharArray();
for (int i = 0; i < chars.length; i++) {
if (chars[i] == gone) {
chars[i] = here;
}
}
return new String(chars);
}
In for loop u had checked whether gone to chars each character and changed value but that changed variable not used to change the again "chars". you had changed value of variable c every time but never used so u got "Supper" as it is. so if u want to change "Supper" then use following code
public static String change(String word, char gone, char here) {
char[] chars = word.toCharArray();
for (int i = 0; i < chars.length; i++) {
if (chars[i] == gone) {
chars[i] = here;
}
}
return new String(chars);
}
What you did there is just change the local variable c not the element in the char array
It's not working because
for (char c : chars)
here you are creating a new variable c which contains a COPY of the character you are currently iterating over.
What you could do instead is using a c-style for loop, iterate over each array element and replace the element within the array, something like:
for (int i = 0; i < chars.length; i++) {
if (char[i] == gone) {
char[i] == here;
}
}
Or even better: Skip the loop and use Strings replace method.
No, java does not COPYing object in For loop, but you are not using object in this example. "char" is primitive variable so you always receive a copy of a primitive veriable.
Related
Given the string in the form of char array. Modify it the way that all the exclamation point symbols '!' are shifted to the start of the array, and all ohters are in the same order. Please write a method with a single argument of type char[]. Focus on either memory and time consumption of alghoritm.
Feedback that i've received: it was possible to use working with arrays instead of strings. Where can i find info about memory?
public static String formatString(char[] chars) {
StringBuilder exclamationSymbols = new StringBuilder();
StringBuilder otherSymbols = new StringBuilder();
for (char c : chars) {
if (c == '!') {
exclamationSymbols.append(c);
} else {
otherSymbols.append(c);
}
}
return (exclamationSymbols.toString() + otherSymbols.toString());
}
You can do this faster using a char[] than a StringBuilder because:
a StringBuilder is just a wrapper around a char[], so there's no way it can be faster. The indirection means it will be slower.
you know exactly how long the result will be, so you can allocate the minimum-sized char[] that you'll need. With a StringBuilder, you can pre-size it, but with two StringBuilders you can't exactly, so you either have to over-allocate the length (e.g. make both the same length as chars) or rely on StringBuilder resizing itself internally (which will be slower than not; and it uses moer memory).
My idea would be to use two integer pointers to point to the next position that you'll write a char to in the string: one starts at the start of the array, the other starts at the end; as you work your way through the input, the two pointers will move closer together.
Once you've processed the entire input, the portion of the result array corresponding to the "end pointer" will be backwards, so reverse it.
You can do it like this:
char[] newChars = new char[chars.length];
int left = 0;
int right = chars.length;
for (char c : chars) {
if (c == '!') {
newChars[left++] = c;
} else {
newChars[--right] = c;
}
}
// Reverse the "otherSymbols".
for (int i = right, j = newChars.length - 1; i < j; ++i, --j) {
char tmp = newChars[i];
newChars[i] = newChars[j];
newChars[j] = tmp;
}
return new String(newChars);
Ideone demo
If I want to create a dictionary where the user can create a custom alphabet (that still uses unicode) Is there a way to change lowercase and uppercase mapping of the characters?
Let's say I want the lowercase of 'I' to be 'ı' instead of 'i' or upperCase of 'b' to be 'P' instead of 'B' so that System.out.println("PAI".toLowerCase()); would write baı to the console.
I suppose I can create a method toLowerCase(String s) that first replaces "P" with "b"s then converts to lowercase but wouldn't that be slower when searching through a dictionary of hundreds of thousands of words?
The toLowerCase(String s) uses the locale to decide how to convert the characters, you should have to define your own locale and then, for example, load it as the default locale via Locale.setDefault(Locale) before executing the toLowerCase(String s)
No, it would not be slower because you are simply traversing through the array and not modifying the position of any object which would result in O(n). Performance wouldn't be affected, and any system should be able to handle a single conversion and then toLowerCase call easily.
You could also override the toLowerCase(String s) function to accommodate your needs. Even simpler!
This should do the trick:
import java.util.HashMap;
import java.util.Map;
class MyString {
String string;
static final Map<Character, Character> toLowerCaseMap, toUpperCaseMap;
static {
toLowerCaseMap = new HashMap<>();
toLowerCaseMap.put('I', '|');
toUpperCaseMap = new HashMap<>();
toUpperCaseMap.put('b', 'P');
}
MyString(String string) {
this.string = string;
}
String toLowerCase() {
char[] chars = string.toCharArray();
for (int i = 0; i < chars.length; i++) {
char c = chars[i];
chars[i] = toLowerCaseMap.containsKey(c) ? toLowerCaseMap.get(c) : Character.toLowerCase(c);
}
return new String(chars);
}
String toUpperCase() {
char[] chars = string.toCharArray();
for (int i = 0; i < chars.length; i++) {
char c = chars[i];
chars[i] = toUpperCaseMap.containsKey(c) ? toUpperCaseMap.get(c) : Character.toUpperCase(c);
}
return new String(chars);
}
}
Check this Answer you cannot inherits from String Class because its final, but you could create your class with your toLowerCase Method, I suggest you called diferents for maintenance.
And for the dictionary of hundreds of thousands of words....
Maybe you use a Map or HashMap with the key will be the string enter by the user and in the object you maybe save automatically the value in lowerCase, it depends of what you need.
But for get better performance I could recommend save the value in Database
Regards.
I need to check if an element of a java array of characters is empty. I tried out the following code but didn't work. What's wrong?
char c[] = new char[3];
c[0] = 'd';
for (int i = 0; i < c.length; i++) {
if(c[i] == null) {
System.out.println(i + " is empty");
}
}
Let's take arrays out of the equation - an array is just a collection of variables, really. Let's consider a single variable. Suppose we had a method like this:
public boolean isEmpty(char c)
What would that do? The value of c cannot be null, because char is a primitive type. It could be U+0000 (aka '\u0000' or '\0' as character literals in Java), and that's the default value of char (for array elements and fields) but it's not the same as a null reference.
If you want a type which is like char but is a reference type, you should consider using Character - the wrapper type for char just like Integer is for int. Or if you know that you'll never use U+0000 as a valid value, you could just stick with that.
However, a better alternative would often be to design your code so that you don't need the concept of "empty or not empty". We don't know what you're trying to achieve here, but it's usually a good thing to at least consider. For arrays, the alternative is often to use an ArrayList<E> - but of course you can't have an ArrayList<char> in Java as Java generics don't allow primitive type arguments :(
An element of a primitive array can't be null. It will always have a default value if you didn't initialize it yourself. The default for char is 0.
Use Character class instead primitive char.
Character c[] = new Character[3];
c[0] = 'd';
for(int i = 0; i < c.length; i++){
if(c[i] == null){
System.out.println(i + " is empty");
}
}
You cannot use null as char is a primitive type. null only works for objects. use \0 as it's the primitive version of null.
primitive char's default value is 0. you can check it with 0
char c[] = new char[3];
c[0] = 'd';
for(int i = 0; i < c.length; i++){
if(c[i] == 0){
System.out.println(i + " is empty");
}
}
even, char=0 is also a character
Is your code compiling?
You should be seeing an error message at this code line if(c[i] == null)
And from error message, compiler is clearly revealing that "the operator == is undefined for argument type(s) char,null".
This should suffice that element of a primitive array (character array in this case)can't be null.
Replace null with '\0' with the quotes
I am getting error saying "The type of the expression must be an array type but it resolved to String"
public class StringWord {
public static void main(String[] args) {
String s = new String("Ahmedabad");
int count = 0;
System.out.println(s.length());
for(int i = 0; i < s.length(); i++){
if(s[i].equals("A")||s[i].equals("a")||s[i].equals("e")||
s[i].equals("E")||s[i].equals("i")||s[i].equals("I")||
s[i].equals("o")||s[i].equals("O")||s[i].equals("u")||
s[i].equals("U"))
{
count++;
}
}
System.out.println("Vowels in a string: "+count);
}
}
if(s[i].equals("A")||s[i].equals("a")||s[i].equals("e")||s[i].equals("E")||s[i].equals("i")
||s[i].equals("I")||s[i].equals("o")||s[i].equals("O")||s[i].equals("u")||s[i].equals("U"))
equals method compares two strings. Here you want to compare character.
use s.charAt(i) instead of s[i] since you want to compare two characters. To get the character at the index i charAt(index) method can be used. Two compare two character == operator is used.
if(s.charAt(i)=='A'||s.charAt(i)=='E'||s.charAt(i)=='I'||s.charAt(i)=='O'||s.charAt(i)=='U')||s.charAt(i)=='a'||s.charAt(i)=='e'||s.charAt(i)=='i'||s.charAt(i)=='o'||s.charAt(i)=='u')
Your variable s is a String, but you treated it like an array by doing s[i].
You should use
s.charAt(i) // a method of String class which returns the char at the index i
instead of s[i].
Strings cannot be accessed by someString[index] (this notation is used for arrays).
Use charAt(index) instead, but note that charAt() returns a char, so you have to compare it with == not with equals() that is used for Strings.
You can also simplify this by:
if ("AaEeIiOoUu".contains(Character.toString(s.charAt(i))) )
{...}
Java String objects aren't character arrays, and you can't use array syntax with them. Instead, you need to use charAt, which returns a char, not a String like you're apparently expecting, and you would need to use == to compare primitives:
if(s.charAt(i) == 'a' || ...)
Additionally, you can use the indexOf method to dramatically simplify your if statement:
static final String VOWELS = "aeiouAEIOU";
for(int i = 0; i < s.length(); i++)
if(VOWELS.indexOf(s.charAt(i)) > -1
count++;
Yes. You are using String s here. There is no index there. Use char array from s. Or you can use s.charAt(index)
INCORRECT. PLEASE DISREGARD
You need to convert the string to an array.
s.ToCharArray();
Note: this is c# code, I don't know if it is similar to java.
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);
}