Get string character by index - java

I know how to work out the index of a certain character or number in a string, but is there any predefined method I can use to give me the character at the nth position? So in the string "foo", if I asked for the character with index 0 it would return "f".
Note - in the above question, by "character" I don't mean the char data type, but a letter or number in a string. The important thing here is that I don't receive a char when the method is invoked, but a string (of length 1). And I know about the substring() method, but I was wondering if there was a neater way.

The method you're looking for is charAt. Here's an example:
String text = "foo";
char charAtZero = text.charAt(0);
System.out.println(charAtZero); // Prints f
For more information, see the Java documentation on String.charAt. If you want another simple tutorial, this one or this one.
If you don't want the result as a char data type, but rather as a string, you would use the Character.toString method:
String text = "foo";
String letter = Character.toString(text.charAt(0));
System.out.println(letter); // Prints f
If you want more information on the Character class and the toString method, I pulled my info from the documentation on Character.toString.

You want .charAt()
Here's a tutorial
"mystring".charAt(2)
returns s
If you're hellbent on having a string there are a couple of ways to convert a char to a string:
String mychar = Character.toString("mystring".charAt(2));
Or
String mychar = ""+"mystring".charAt(2);
Or even
String mychar = String.valueOf("mystring".charAt(2));
For example.

None of the proposed answers works for surrogate pairs used to encode characters outside of the Unicode Basic Multiligual Plane.
Here is an example using three different techniques to iterate over the "characters" of a string (incl. using Java 8 stream API). Please notice this example includes characters of the Unicode Supplementary Multilingual Plane (SMP). You need a proper font to display this example and the result correctly.
// String containing characters of the Unicode
// Supplementary Multilingual Plane (SMP)
// In that particular case, hieroglyphs.
String str = "The quick brown ๐“ƒฅ jumps over the lazy ๐“Šƒ๐“ฟ๐“…“๐“ƒก";
Iterate of chars
The first solution is a simple loop over all char of the string:
/* 1 */
System.out.println(
"\n\nUsing char iterator (do not work for surrogate pairs !)");
for (int pos = 0; pos < str.length(); ++pos) {
char c = str.charAt(pos);
System.out.printf("%s ", Character.toString(c));
// ^^^^^^^^^^^^^^^^^^^^^
// Convert to String as per OP request
}
Iterate of code points
The second solution uses an explicit loop too, but accessing individual
code points with codePointAt and incrementing the loop index accordingly to charCount:
/* 2 */
System.out.println(
"\n\nUsing Java 1.5 codePointAt(works as expected)");
for (int pos = 0; pos < str.length();) {
int cp = str.codePointAt(pos);
char chars[] = Character.toChars(cp);
// ^^^^^^^^^^^^^^^^^^^^^
// Convert to a `char[]`
// as code points outside the Unicode BMP
// will map to more than one Java `char`
System.out.printf("%s ", new String(chars));
// ^^^^^^^^^^^^^^^^^
// Convert to String as per OP request
pos += Character.charCount(cp);
// ^^^^^^^^^^^^^^^^^^^^^^^
// Increment pos by 1 of more depending
// the number of Java `char` required to
// encode that particular codepoint.
}
Iterate over code points using the Stream API
The third solution is basically the same as the second, but using the Java 8 Stream API:
/* 3 */
System.out.println(
"\n\nUsing Java 8 stream (works as expected)");
str.codePoints().forEach(
cp -> {
char chars[] = Character.toChars(cp);
// ^^^^^^^^^^^^^^^^^^^^^
// Convert to a `char[]`
// as code points outside the Unicode BMP
// will map to more than one Java `char`
System.out.printf("%s ", new String(chars));
// ^^^^^^^^^^^^^^^^^
// Convert to String as per OP request
});
Results
When you run that test program, you obtain:
Using char iterator (do not work for surrogate pairs !)
T h e q u i c k b r o w n ? ? j u m p s o v e r t h e l a z y ? ? ? ? ? ? ? ?
Using Java 1.5 codePointAt(works as expected)
T h e q u i c k b r o w n ๐“ƒฅ j u m p s o v e r t h e l a z y ๐“Šƒ ๐“ฟ ๐“…“ ๐“ƒก
Using Java 8 stream (works as expected)
T h e q u i c k b r o w n ๐“ƒฅ j u m p s o v e r t h e l a z y ๐“Šƒ ๐“ฟ ๐“…“ ๐“ƒก
As you can see (if you're able to display hieroglyphs properly), the first solution does not handle properly characters outside of the Unicode BMP. On the other hand, the other two solutions deal well with surrogate pairs.

You're pretty stuck with substring(), given your requirements. The standard way would be charAt(), but you said you won't accept a char data type.

You could use the String.charAt(int index) method result as the parameter for String.valueOf(char c).
String.valueOf(myString.charAt(3)) // This will return a string of the character on the 3rd position.

A hybrid approach combining charAt with your requirement of not getting char could be
newstring = String.valueOf("foo".charAt(0));
But that's not really "neater" than substring() to be honest.

It is as simple as:
String charIs = string.charAt(index) + "";

Here's the correct code. If you're using zybooks this will answer all the problems.
for (int i = 0; i<passCode.length(); i++)
{
char letter = passCode.charAt(i);
if (letter == ' ' )
{
System.out.println("Space at " + i);
}
}

if someone is strugling with kotlin, the code is:
var oldStr: String = "kotlin"
var firstChar: String = oldStr.elementAt(0).toString()
Log.d("firstChar", firstChar.toString())
this will return the char in position 1, in this case k
remember, the index starts in position 0, so in this sample:
kotlin would be k=position 0, o=position 1, t=position 2, l=position 3, i=position 4 and n=position 5

CodePointAt instead of charAt is safer to use. charAt may break when there are emojis in the strtng.

CharAt function not working
Edittext.setText(YourString.toCharArray(),0,1);
This code working fine

I come across this question yeasterday and I am aware this has accepted answer, just want to add one more solution to this in javascript scenario which can help people like me who are looking for this -
let name = 'Test'
console.log(name[2])
// Here at index 2 we have 's' value and this will simply give the expected output

Like this:
String a ="hh1hhhhhhhh";
char s = a.charAt(3);

Related

Converting letters to alphabet position with two JLists

I'm trying to replace all words (alphabet letters) from JList1 to the number corresponding its place in the alphabet to JList2 with the press of the Run button. (ex. A to 01) And if it's not an English alphabet letter then leaving it as it is. Capitalization doesn't matter (a and A is still 01) and spaces should be kept.
For visual purposes:
"Apple!" should be converted to "0116161205!"
"stack Overflow" to "1920010311 1522051806121523"
"รผber" to "รผ020518"
I have tried a few methods I found on here, but had zero clue how to add the extra 0 in front of the first 9 letters or keep the spaces. Any help is much appreciated.
Here is a solution :
//Create a Map of character and equivalent number
Map<Character, String> lettersToNumber = new HashMap<>();
int i = 1;
for(char c = 'a'; c <= 'z'; c++) {
lettersToNumber.put(c, String.format("%02d", i++));
}
//Loop over the characters of your input and the corresponding number
String result = "";
for(char c : "Apple!".toCharArray()) {
char x = Character.toLowerCase(c);
result+= lettersToNumber.containsKey(x) ? lettersToNumber.get(x) : c;
}
Input, Output
Apple! => 0116161205!
stack Overflow => 1920010311 1522051806121523
รผber => รผ020518
So given...
(ex. A to 01) And if it's not an English alphabet letter then leaving it as it is. Capitalization doesn't matter (a and A is still 01) and spaces should be kept.
This raises some interesting points:
We don't care about non-english characters, so we can dispense with issues around UTF encoding
Capitalization doesn't matter
Spaces should be kept
The reason these points are interesting to me is it means we're only interested in a small subset of characters (1-26). This immediately screams "ASCII" to me!
This provides an immediate lookup table which doesn't require us to produce anything up front, it's immediately accessible.
A quick look at any ascii table provides us with all the information we need. A-Z is in the range of 65-90 (since we don't care about case, we don't need to worry about the lower case range.
But how does that help us!?
Well, this now means the primary question becomes, "How do we convert a char to an int?", which is amazingly simple! A char can be both a "character" and a "number" at the same time, because of the ASCII encoding support!
So if you were to print out (int)'A', it would print 65! And since all the characters are in order, we just need to subtract 64 from 65 to get 1!
That's basically your entire problem solved right there!
Oh, okay, you need to deal with the edge cases of characters not falling between A-Z, but that's just a simple if statement
A solution based on the above "might" look something like...
public static String convert(String text) {
int offset = 64;
StringBuilder sb = new StringBuilder(32);
for (char c : text.toCharArray()) {
char input = Character.toUpperCase(c);
int value = ((int) input) - offset;
if (value < 1 || value > 25) {
sb.append(c);
} else {
sb.append(String.format("%02d", value));
}
}
return sb.toString();
}
Now, there are a number of ways you might approach this, I've chosen a path based on my understanding of the problem and my experience.
And based on your example input...
String[] test = {"Apple!", "stack Overflow", "รผber"};
for (String value : test) {
System.out.println(value + " = " + convert(value));
}
would produce the following output...
Apple! = 0116161205!
stack Overflow = 1920010311 1522051806121523
รผber = รผ020518

Replacing a character in a string from another string with the same char index

I'm trying to search and reveal unknown characters in a string. Both strings are of length 12.
Example:
String s1 = "1x11222xx333";
String s2 = "111122223333"
The program should check for all unknowns in s1 represented by x|X and get the relevant chars in s2 and replace the x|X by the relevant char.
So far my code has replaced only the first x|X with the relevant char from s2 but printed duplicates for the rest of the unknowns with the char for the first x|X.
Here is my code:
String VoucherNumber = "1111x22xx333";
String VoucherRecord = "111122223333";
String testVoucher = null;
char x = 'x'|'X';
System.out.println(VoucherNumber); // including unknowns
//find x|X in the string VoucherNumber
for(int i = 0; i < VoucherNumber.length(); i++){
if (VoucherNumber.charAt(i) == x){
testVoucher = VoucherNumber.replace(VoucherNumber.charAt(i), VoucherRecord.charAt(i));
}
}
System.out.println(testVoucher); //after replacing unknowns
}
}
I am always a fan of using StringBuilders, so here's a solution using that:
private static String replaceUnknownChars(String strWithUnknownChars, String fullStr) {
StringBuilder sb = new StringBuilder(strWithUnknownChars);
while ((int index = Math.max(sb.toString().indexOf('x'), sb.toString().indexOf('X'))) != -1) {
sb.setCharAt(index, fullStr.charAt(index));
}
return sb.toString();
}
It's quite straightforward. You create a new string builder. While a x or X can still be found in the string builder (indexOf('X') != -1), get the index and setCharAt.
Your are using String.replace(char, char) the wrong way, the doc says
Returns a new string resulting from replacing all occurrences of oldChar in this string with newChar.
So you if you have more than one character, this will replace every one with the same value.
You need to "change" only the character at a specific spot, for this, the easiest is to use the char array that you can get with String.toCharArray, from this, this is you can use the same logic.
Of course, you can use String.indexOf to find the index of a specific character
Note : char c = 'x'|'X'; will not give you the expected result. This will do a binary operation giving a value that is not the one you want.
The OR will return 1 if one of the bit is 1.
0111 1000 (x)
0101 1000 (X)
OR
0111 1000 (x)
But the result will be an integer (every numeric operation return at minimum an integer, you can find more information about that)
You have two solution here, you either use two variable (or an array) or if you can, you use String.toLowerCase an use only char c = 'x'

Find every possible subset given a string [duplicate]

This question already has answers here:
Memory efficient power set algorithm
(5 answers)
Closed 8 years ago.
I'm trying to find every possible anagram of a string in Java - By this I mean that if I have a 4 character long word I want all the possible 3 character long words derived from it, all the 2 character long and all the 1 character long. The most straightforward way I tought of is to use two nested for loops and iterare over the string. This is my code as of now:
private ArrayList<String> subsets(String word){
ArrayList<String> s = new ArrayList<String>();
int length = word.length();
for (int c=0; c<length; c++){
for (int i=0; i<length-c; i++){
String sub = word.substring(c, c+i+1);
System.out.println(sub);
//if (!s.contains(sub) && sub!=null)
s.add(sub);
}
}
//java.util.Collections.sort(s, new MyComparator());
//System.out.println(s.toString());
return s;
}
My problem is that it works for 3 letter words, fun yelds this result (Don't mind the ordering, the word is processed so that I have a string with the letters in alphabetical order):
f
fn
fnu
n
nu
u
But when I try 4 letter words, it leaves something out, as in catq gives me:
a
ac
acq
acqt
c
cq
cqt
q
qt
t
i.e., I don't see the 3 character long word act - which is the one I'm looking for when testing this method. I can't understand what the problem is, and it's most likely a logical error I'm making when creating the substrings. If anyone can help me out, please don't give me the code for it but rather the reasoning behind your solution. This is a piece of coursework and I need to come up with the code on my own.
EDIT: to clear something out, for me acq, qca, caq, aqc, cqa, qac, etc. are the same thing - To make it even clearer, what happens is that the string gets sorted in alphabetical order, so all those permutations should come up as one unique result, acq. So, I don't need all the permutations of a string, but rather, given a 4 character long string, all the 3 character long ones that I can derive from it - that means taking out one character at a time and returning that string as a result, doing that for every character in the original string.
I hope I have made my problem a bit clearer
It's working fine, you just misspelled "caqt" as "acqt" in your tests/input.
(The issue is probably that you're sorting your input. If you want substrings, you have to leave the input unsorted.)
After your edits: see Generating all permutations of a given string Then just sort the individual letters, and put them in a set.
Ok, as you've already devised your own solution, I'll give you my take on it. Firstly, consider how big your result list is going to be. You're essentially taking each letter in turn, and either including it or not. 2 possibilities for each letter, gives you 2^n total results, where n is the number of letters. This of course includes the case where you don't use any letter, and end up with an empty string.
Next, if you enumerate every possibility with a 0 for 'include this letter' and a 1 for don't include it, taking your 'fnu' example you end up with:
000 - ''
001 - 'u'
010 - 'n'
011 - 'nu'
100 - 'f'
101 - 'fu' (no offense intended)
110 - 'fn'
111 - 'fnu'.
Clearly, these are just binary numbers, and you can derive a function that given any number from 0-7 and the three letter input, will calculate the corresponding subset.
It's fairly easy to do in java.. don't have a java compiler to hand, but this should be approximately correct:
public string getSubSet(string input, int index) {
// Should check that index >=0 and < 2^input.length here.
// Should also check that input.length <= 31.
string returnValue = "";
for (int i = 0; i < input.length; i++) {
if (i & (1 << i) != 0) // 1 << i is the equivalent of 2^i
returnValue += input[i];
}
return returnValue;
}
Then, if you need to you can just do a loop that calls this function, like this:
for (i = 1; i < (1 << input.length); i++)
getSubSet(input, i); // this doesn't do anything, but you can add it to a list, or output it as desired.
Note I started from 1 instead of 0- this is because the result at index 0 will be the empty string. Incidentally, this actually does the least significant bit first, so your output list would be 'f', 'n', 'fn', 'u', 'fu', 'nu', 'fnu', but the order didn't seem important.
This is the method I came up with, seems like it's working
private void subsets(String word, ArrayList<String> subset){
if(word.length() == 1){
subset.add(word);
return;
}
else {
String firstChar = word.substring(0,1);
word = word.substring(1);
subsets(word, subset);
int size = subset.size();
for (int i = 0; i < size; i++){
String temp = firstChar + subset.get(i);
subset.add(temp);
}
subset.add(firstChar);
return;
}
}
What I do is check if the word is bigger than one character, otherwise I'll add the character alone to the ArrayList and start the recursive process. If it is bigger, I save the first character and make a recursive call with the rest of the String. What happens is that the whole string gets sliced in characters saved in the recursive stack, until I hit the point where my word has become of length 1, only one character remaining.
When that happens, as I said at the start, the character gets added to the List, now the recursion starts and it looks at the size of the array, in the first iteration is 1, and then with a for loop adds the character saved in the stack for the previous call concatenated with every element in the ArrayList. Then it adds the character on its own and unwinds the recursion again.
I.E., with the word funthis happens:
f saved
List empty
recursive call(un)
-
u saved
List empty
recursive call(n)
-
n.length == 1
List = [n]
return
-
list.size=1
temp = u + list[0]
List = [n, un]
add the character saved in the stack on its own
List = [n, un, u]
return
-
list.size=3
temp = f + list[0]
List = [n, un, u, fn]
temp = f + list[1]
List = [n, un, u, fn, fun]
temp = f + list[2]
List = [n, un, u, fn, fun, fu]
add the character saved in the stack on its own
List = [n, un, u, fn, fun, fu, f]
return
I have been as clear as possible, I hope this clarifies what was my initial problem and how to solve it.
This is working code:
public static void main(String[] args) {
String input = "abcde";
Set<String> returnList = permutations(input);
System.out.println(returnList);
}
private static Set<String> permutations(String input) {
if (input.length() == 1) {
Set<String> a = new TreeSet<>();
a.add(input);
return a;
}
Set<String> returnSet = new TreeSet<>();
for (int i = 0; i < input.length(); i++) {
String prefix = input.substring(i, i + 1);
Set<String> permutations = permutations(input.substring(i + 1));
returnSet.add(prefix);
returnSet.addAll(permutations);
Iterator<String> it = permutations.iterator();
while (it.hasNext()) {
returnSet.add(prefix + it.next());
}
}
return returnSet;
}

Creating a simple encryption program

I'd like to use java to make a cipher of sorts, but im not sure how to go about it.
Basically, I'd want the machine to accept a string of text, say "Abcd"
and then a key, say '4532'
The program should move the characters forward in the alphabet if the number matching the place of the letter is even, and backward if it's odd.
If there is no number, the key should loop around until it's out of characters in the string to change.
the program would then print the key. Ideally, if im pseudocoding this correctly, deciphering the string would be a reverse process only applicable with the key.
I'm guessing i'd use a combination of an array and if/else statements.
I'm not sure where to start.
Example & edit String: 'hello' Key: '12'
a b c d e f g h i j k l m n o p q r s t u v w x y z
Because the corresponding key value is 1, h will travel backwards that many spaces.
h = g
because e has a 2, it'll move forward that many spaces.
e = g
the first l then becomes k, while the second becomes n. The Key is repeated because the string is out of numbers to compare. o turns into n because it's matched with 1.
hello would become ggknn with the key 42.
Here are possible steps you can take to do this. This is not an exact and working solution, but it will hopefully get you started.
Start by reading input from the console (via Scanner or a BufferedReader for example).
Split your input on spaces perhaps, so that you have a String[] of words.
Loop through the String[] of words, and loop again for which word. You can have a counter that is incremented in each iteration of an inner loop and gets reset at the end of an inner loop. You can use that counter variable to get a position into the key (key[counter%lengthOfKey]) in each iteration of the inner loop. If the (counter%lengthOfKey)%2 == 0, you have the even number case for the key, else the odd numbered case. Do whatever encryption at that point (simple substitution cipher for example).
There are many methods of Encryption, but if you want to learn about Encryption you should start with the study of XOR encryption. XOR Encryption uses a key and XORs the binary code of every character with the key. If the key is longer than the encrypted code it creates a One-Time Pad that is impossible to decrypt.
XOR - Exclusive OR - Unlike OR both values can not be true at the same time.
Simple Explanation:
Pretend you want to encrypt the string "hello world" with the key 'c'.
For every character in the string XOR it with the key c.
Pretend the binary value of h is 1100011 and the binary value of c is 0010110 (these are made up and will not work) then you XOR every corresponding binary value.
1100011
XOR
0010110
-------
1110101
1110101 is the XORed binary value.
You then cast the binary value back into character and you do this for every step of the encrypted string.
Problems:
Insecure for short keys. but very powerful for long keys and creates a one time pad.
Example code:
http://www.ecestudents.ul.ie/Course_Pages/Btech_ITT/Modules/ET4263/More%20Samples/CEncrypt.java.html
Find below the class for encyption
public class App
{
public static void main(String arg[])
{
String keys = "12";
String codes = "hello";
StringBuilder result = new StringBuilder();
char[] codeList = codes.toCharArray();
char[] keyList = keys.toCharArray();
int maxCount = keys.length();
System.out.println("The length is "+maxCount);
int i = 0;
for (Character code : codeList) {
int key = Character.getNumericValue(keyList[i]);
if(key % 2 == 0)
{
int res = code+key;
result.append((char)res);
}
else
{
int res = code-key;
result.append((char)res);
}
i++;
if(i==maxCount)
{
i = 0;
}
}
System.out.println("The result is "+result.toString());
}
}

Shifting letters in a String Java

I'm trying to make a program that takes a string and shifts the letters int it by 3 positions.
Example:
Input "AGZ"
Output:"DKC"
I've tried looking at oracles String document about this but I couldn't find anything that I could use. Any tips?
All chars correspond to an int value based on ASCII, so you can do something like this:
String input = "AGZ";
String output = "";
for (char c : input.toCharArray())
output += (char) (c + 3);
Note that this doesn't wrap the Z around to a C, but I wouldn't want to take all the fun from ya.

Categories