(EDITED)
My problem statement: write a method that will encode the String passed to the method by adding 13 letters to each character in the String. If the letter after adding 13 exceeds 'z' then "wrap around" the alphabet. Then return the encoded String.
encodeString("hello") → "uryyb"
encodeString("pie") → "cvr"
encodeString("book") → "obbx"
this is what I have so far :
public static String encodeString (String input) {
String output;
for (int i = 0; i < input.length(); i++) {
char c = input.charAt(i);
if (c >= 'a' && c <= 'm')
c += 13;
else if (c >= 'n' && c <= 'z')
c -= 13;
output= (" " + (c));
}
return output;
}
now I know that I have to create a counter so that the method will continue to loop until it reaches the length of the string passed...and I know that if the charAt(index) is less than the character 'n' that I add 13 and if it is greater then I subtract 13. when I put it all together though I just get so confused and just get a bunch of compiling errors like Type mismatch: cannot convert from int to String.
note straightforward explanations/answers would be much appreciated...
***so now my problem is that it keeps telling me my output variable may not have been initialized
This code is not the most performatic but works good with Upper and Lower characters.
hElLo → uRyYb
pIe → cVr
bOoK → oBbX
private static String encodeString(String string) {
char[] ret = new char[string.length()];
for (int i = 0; i < string.length(); i++) {
ret[i] = rot13(string.charAt(i));
}
return String.valueOf(ret);
}
public static char rot13(char c) {
if (Character.isLetter(c)) {
if (Character.compare(Character.toLowerCase(c), 'a') >= 0
&& Character.compare(Character.toLowerCase(c), 'm') <= 0)
return c += 13;
else
return c -= 13;
}
return c;
}
You have to initialize your output variable as an empty String. Furthermore you are always replacing the contents of the output variable with the last char you've just encoded. So you have to add every char to the output with += instead of =.
So here is the fixed solution:
public static String encodeString(String input) {
String output = ""; // initialize as empty String
for (int i = 0; i < input.length(); i++) {
char c = input.charAt(i);
if (c >= 'a' && c <= 'm') {
c += 13;
} else if (c >= 'n' && c <= 'z') {
c -= 13;
}
output += " " + c; // add all chars to the String instead of replacing the whole String with "="!
}
return output;
}
I beautified your code a bit, so everybody can see what it really does.
Use an IDE!
Related
This question already has answers here:
What causes a java.lang.ArrayIndexOutOfBoundsException and how do I prevent it?
(26 answers)
Closed 4 years ago.
I have been trying to find my own way of making a Rot13 algorithm in java, but when I try a phrase, it gives me this error:
java.lang.ArrayIndexOutOfBoundsException: 41
So this is my code:
:Update with whole names,
public class Rot13
{
char[] translated;
String abc = "abcdefghijklmnopjrstuvwxyzabcdefghijklmnopqrstuvwxyz";
public String ROT13(String input){
input = input.toLowerCase();
char[] sentence = input.toCharArray();
char[] ABC = abc.toCharArray();
int x = input.length();
int y = 0;
char[] translated = new char[x];
for(int i = 0; i<x;i++){
int z = 0;
if(sentence[i] == ' '){
translated[i] = ' ';
}
else {
while(y==0){
if (sentence[i] == ABC[z]){
y =1;
}
else{
z += 1;
}
}
translated[i] = ABC[z+12];
}
}
String rot13string = new String(translated);
return rot13string;
}
}
: Update 2
I just tested this version again and it translates the it. But in the wrong way, for example, "Hello" becomes "tmmmm" The first letter seems to be right but then the next ones are always 'm'.
Update 3: Thanks for your answers guys, here is my final code, I just duplicated my alphabet a "few" times. :
public class ROT13
{
char[] translated;
String ab = "abcdefghijklmnopjrstuvwxyzabcdefghijklmnopqrstuvwxyz";
String abc = String.format("%0" + 1000 + "d", 0).replace("0",ab);
public String ROT13(String input){
input = input.toLowerCase();
char[] sentence = input.toCharArray();
char[] ABC = abc.toCharArray();
int length = input.length();
char[] translated = new char[length];
for(int i = 0; i<length;i++){
int y = 0;
int h = 0;
if(sentence[i] == ' '){
translated[i] = ' ';
}
else {
while(y==0){
int z = 0;
if (sentence[i] == ABC[h]){
y +=1;
}
else{
z += 1;
h += 1;
}
}
translated[i] = ABC[h+13];
}
}
String rot13string = new String(translated);
return rot13string;
}
}
Currently, think about what happens when there is a 'z' in the sentence. Then, you make t[i] = ABC[z (26) + 12] //which is larger than ABC's length.
Personally, I would do rot13 like so:
public char rot13(char s){
if (c >= 'a' && c <= 'm') return c += 13;
else if (c >= 'A' && c <= 'M') return c += 13;
else if (c >= 'n' && c <= 'z') return c -= 13;
else if (c >= 'N' && c <= 'Z') return c -= 13;
else return c;
}
How can I add 0 in front of every single digit number? I mean 1 to 01 etc.
I have tried to add ifs like
if(c >='A' && c<= 'I')
str = "0"+str;
but it just adds 0 in front of everything like abcd converts to 00001234 not 01020304.
This is my code.
String A[] = new String[size];
for (int i = 0; i < size; i++) {
A[i] = jList1.getModel().getElementAt(i);
String[] Text = A[i].split("");
String s = jList1.getModel().getElementAt(i);
String str = ("");
for (int z = 0; z < Text.length; z++) {
for (int y = 0; y < Text[z].length(); y = y + 1) {
char c = s.charAt(z);
if (c >= 'A' && c <= 'Z') {
str += c - 'A' + 1;
} else if (c >= 'a' && c <= 'z') {
str += c - 'a' + 1;
} else {
str += c;
}
}
str = str + "";
}
}
This Worked for me
public String addZero(int number)
{
return number<=9?"0"+number:String.valueOf(number);
}``
One way to do this would be to use a StringJoiner with Java 8:
String s = "abcdABCD";
s = s.chars()
.mapToObj(i -> Integer.toString((i >= 'a' && i <= 'z' ? i - 'a' : i - 'A') + 1))
.collect(Collectors.joining("0", "0", "")));
System.out.println(s);
>> 0102030401020304
String str = "abcd-zzz-AAA";
StringBuilder sb = new StringBuilder();
for (int i = 0; i < str.length(); i++) {
char ch = str.toLowerCase().charAt(i);
if (ch >= 'a' && ch <= 'z') {
sb.append('0');
sb.append(ch - 'a' + 1);
} else {
sb.append(ch);
}
}
Result: abcd-zzz-AAA -> 01020304-026026026-010101
Final fix :-)
use String#chars to get a stream of its characters, then for each one do the manipulation you want.
public class Example {
public static void main(String[] args) {
String s = "aBcd1xYz";
s.chars().forEach(c -> {
if (c >= 'a' && c <= 'z')
System.out.print("0" + (c - 'a' + 1));
else if (c >= 'A' && c <= 'Z')
System.out.print("0" + (c - 'A' + 1));
else
System.out.print(c);
});
}
}
Ouput:
0102030449024025026
You can add zero in front of single digit number using String.format.
System.out.println(String.format("%02d",1));
System.out.println(String.format("%02d",999));
The first line will print 01, second line prints 999 no zero padding on the left.
Padding zero with length of 2 and d represents integer.
I hope this helps.
private static String shift(String p, int shift){
String s = "";
int len = p.length();
for(int x = 0; x < len; x++){
char c = (char)(p.charAt(x) + shift);
if (c == ' '){ // this right here isn't working
s += " ";
} else if (c > 'z'){
s += (char)(p.charAt(x) - (26-shift));
}
else {
s += (char)(p.charAt(x) + shift);
}
}
return s;
}
example output: qer$hyhi ( the "$" used to be a space ). Why doesn't the space simply stay a space like it should? instead it still follows the conversion process.
The problem is that you are comparing the already shifted character to space.
There are several ways to fix this bug, one of them is the following (fixing some other minor issues):
private static String shift(String p, int shift){
StringBuilder s = new StringBuilder(); //better using a mutable object than creating a new string in each iteration
int len = p.length();
for(int x = 0; x < len; x++){
char c = p.charAt(x); //no need for casting
if (c != ' '){ // this should work now
c += shift;
if (c > 'z'){ //we assume c is in the 'a-z' range, ignoring 'A-Z'
c -= 'z';
}
}
s.append(c);
}
return s.toString();
}
Hi I am trying to convert from lower to uppercase. I know they are other easier ways to do this, but I want something else. It seems that the program prints out the users input more than once, so I am almost 100% sure it's the loop. But I can't find where the problem is.
String a = input.nextLine();
String c = "";
int b = a.length();
for (int i = 0 ; i < b; i++)
{
if (a.charAt(i) >= 97 && a.charAt(i) <= 122)
{
c = c + a;
System.out.println(c.toUpperCase());
}
}
Actually your code logic wasn't totally right, I mean why would you add the content of a to c? Doesn't make sense, and you excluded the letters a and z in your if.
String a = input.nextLine();
String c = "";
int b = a.length();
for (int i = 0; i < b; i++) {
if (a.charAt(i) >= 97 && a.charAt(i) <= 122) {
c = c + a.charAt(i);
}
}
System.out.println(c.toUpperCase());
You're printing c in each iteration of the loop where the if is entered instead of just once, after it ends.
Why bother going through the loop at all?
String a = input.nextLine();
System.out.println( a.toUpperCase();
will do what you want
If you want to invert the characters:
StringBuffer sb = new StringBuffer(a);
for ( int i=0; i < sb.length(); i++ ) {
char c = sb.charAt(i);
if ( c.isLower() ) {
sb.setCharAt(i,c.toUpper());
} else if ( c.isUpper() ) {
sb.setCharAt(i,c.toLower());
}
}
String result = sb.toString();
This solution should work:
for (int i = 0 ; i < b; i++)
{
if (a.charAt(i) > 97 && a.charAt(i) < 122)
{
a = a.toUpperCase();
}
}
System.out.println(a);
Given an input, I'm trying to write a program to find the minimum base that can be associated with that number. For example the minimum base associated with 385 is base-9 (as it needs to have a base that supports the digit 8 which is its highest value digit). Similarly, the minimum base associated with B95 is base-12, since it uses 0 -9 and A and B.
This is my code
public static int findBase(String str){
int max = 0;
char c;
for (int i = 0; i <str.length() ; i++) {
c = str.toUpperCase().charAt(i);
if (Character.isDigit(c) && c > max) {
max = c;
}else if (Character.isLetter(c)) {
max = 10 + (c - 'A');
}
}
return max + 1;
}
The problem is that the function is returning random values.For example for the value 385 it returns 56. What am I doing wrong?
The problem is that you're using the unicode value of the character when it's a digit.
Instead of:
max = c;
... you should use:
max = c - '0';
Also note that Character.isLetter returns true for all unicode letters, including Arabic letters and letters from other alphabets, that have much higher unicode codepoint values; likewise for Character.isDigit
In your case, you're only capable of handling Latin characters from the ASCII character set, so to be safe it's better to check for that specifically.
And you're not checking correctly for the maximum value (you're comparing the unicode codepoint to the max, not the converted value)
int v = 0;
if (c >= '0' && c <= '9') {
v = c - '0';
} else if (c >= 'A' && c <= 'Z') {
v = 10 + (c - 'A');
}
if (v > max) {
max = v;
}
Full program:
public static int findBase(String str) {
int max = 0;
str = str.toUpperCase();
for (int i = 0; i < str.length(); i++) {
char c = str.charAt(i);
int v = 0;
if (c >= '0' && c <= '9') {
v = c - '0';
} else if (c >= 'A' && c <= 'Z') {
v = 10 + (c - 'A');
}
if (v > max) {
max = v;
}
}
return max + 1;
}