in function "isDigit" java.lang.ArrayIndexOutOfBoundsException: 5 - java

I need to write encryptor.
The first letter needs to be converted to its ASCII code.
The second letter needs to be switched with the last letter
It should make from this "65 119esi 111dl 111lw 108dvei 105n 97n 111ka"
This "A wise old owl lived in an oak"
But when I check is char a digit i have an error.
public static void encryptThis(String text) {
String [] text_arr = text.split("\\s");
for(int i = 0; i < text_arr.length;i++){
String word = text_arr[i];
int length = word.length();
char [] char_word = new char [length];
char_word = word.toCharArray();
int k = 0;
length = char_word.length;
char [] numb = new char [length];
for (int j = 0;j < length; j++){
//In this place
if (Character.isDigit(char_word[i])){
numb[k] = char_word[i];
char_word[i] = ' ';
k++;
System.out.println(numb[k]);
}
}
int number = Integer.parseInt(numb.toString(),8);
String edit_char_word = char_word.toString();
String final_str = new StringBuffer(edit_char_word).reverse().toString().trim();
final_str = number + final_str;
text_arr[i] = final_str;
}
String fin_text = text_arr.toString();
return fin_text;
}

I wrote the encryptThis method from the beginning and tried to stay as simple to get readable code, here is
a full working example. As you did not mention what to do if a number is the first "letter" there is no
special handling for this - an "1" will be encrypted to (ascii) 49...
public class Main_So {
public static void main(String[] args) {
System.out.println("https://stackoverflow.com/questions/62460366/in-function-isdigit-java-lang-arrayindexoutofboundsexception-5");
String input = "A wise old owl lived in an oak";
String outputExpected = "65 119esi 111dl 111lw 108dvei 105n 97n 111ka";
System.out.println("input: " + input);
String output = encryptThis(input);
System.out.println("output encryptThis: " + output);
System.out.println("output expected: " + outputExpected);
}
public static String encryptThis(String text) {
String[] text_arr = text.split("\\s");
String outputString = "";
for (int i = 0; i < text_arr.length; i++) {
String word = text_arr[i];
int length = word.length();
int ascii0 = (int) word.charAt(0);
String word0 = String.valueOf(ascii0); // first char as ascii code
String subString = word.substring(1);
if (length > 2) { // switch chars if string length > 2
char char1 = word.charAt(1);
char charEnd = word.charAt(length - 1);
StringBuilder wordBuilder = new StringBuilder(subString);
wordBuilder.setCharAt(0, charEnd);
wordBuilder.setCharAt((length - 2), char1);
subString = String.valueOf(wordBuilder);
}
outputString = outputString + word0 + subString + " ";
}
return outputString;
}
}
This is the result:
input: A wise old owl lived in an oak
output encryptThis: 65 119esi 111dl 111lw 108dvei 105n 97n 111ka
output expected: 65 119esi 111dl 111lw 108dvei 105n 97n 111ka

Related

Put a space every 5 characters without using regex or StringBuilder

I want a user to put in a sentence with the scanner class.
Make sure to filter out all the spaces (for example the sentence: this is a test becomes thisisatest)
And then print out that sentence with a for loop with a space every 5 characters
(for example thisi sates t).
This is what i have so far
import java.util.Scanner;
public class BlockText {
public static void main(String[] args) {
Scanner s = new Scanner(System.in);
System.out.println("Give your sentence: ");
String sentence = s.nextLine();
String nospace = sentence.replace(" ", "");
String out = "";
for (int i = 5; i < nospace.length(); i+=5) {
out += nospace.replaceAll( nospace.substring(i) , " ");
}
System.out.println("Sentence without spaces: " + nospace);
System.out.println("This gives: " + out);
}
}
but I have the issue that he repeats certain characters and removes others.
Like you can see underneath after "this gives:"
run:
Give your sentence:
this is a test
Sentence without spaces: thisisatest
This gives: thisi hisisa es
BUILD SUCCESSFUL (total time: 8 seconds)
Can someone help me out? Like I said in the titel, I want to accomplish this with a for loop and without using regex or StringBuilder.
You should really use a StringBuilder here, because appending strings with += in a loop is very inefficient.
Without a string builder, you can do something like this:
private static String addSpacesEvery5(String s) {
String out = "";
for (int i = 0 ; i < s.length() ; i++) {
if (i % 5 == 0 && i != 0) {
out += " "; // this will run once every five iterations, except the first one
}
out += s.charAt(i);
}
return out;
}
Or more efficiently without +=:
private static String addSpacesEvery5(String s) {
// s.length() / 5 is how many spaces we will add
char[] charArray = new char[s.length() + s.length() / 5];
int currentPos = 0;
for (int i = 0 ; i < s.length() ; i++) {
if (i % 5 == 0 && i != 0) {
charArray[currentPos] = ' ';
currentPos++;
}
charArray[currentPos] = s.charAt(i);
currentPos++;
}
return new String(charArray);
}
And then you can use it in your main method like this:
Scanner s = new Scanner(System.in);
System.out.println("Give your sentence: ");
String sentence = s.nextLine();
String nospace = sentence.replace(" ", "");
String out = addSpacesEvery5(nospace);
System.out.println("Sentence without spaces: " + nospace);
System.out.println("This gives: " + out);
With a string builder, the addSpacesEvery5 could be rewritten as:
private static String addSpacesEvery5(String s) {
StringBuilder out = new StringBuilder();
for (int i = 0 ; i < s.length() ; i++) {
if (i % 5 == 0 && i != 0) {
out.append(" ");
}
out.append(s.charAt(i));
}
return out.toString();
}
Here is one relatively simple and faster:
String tmp = new String();
int len = str.length();
int remOdds = len % 5;
int i = 0;
while (i < len - remOdds)
{
tmp = tmp.concat(str.substring(i, i + 5));
i += 5;
if (i < len)
{
tmp += " ";
}
}
while (i < len)
{
tmp += str.charAt(i);
i++;
}
str = tmp;

How do you shift char values in an arraylist?

I'm trying to code a cipher project where the objective is for a user to send in a text and shift number. The result would be printed accordingly. For instance, if I sent "Hello World" with a shift value of 1, it should print: "Gfmmp Xrsme". The problem is that I'm having trouble with the shifting because I have an arraylist of char values (the alphabet).
This is what I have so far:
import java.util.ArrayList;
public class CaesarCipher
{
int shift;
String inputText;
ArrayList<String> arr;
ArrayList<String> exchange = new ArrayList<String>();
public CaesarCipher()
{
shift = 0;
inputText = "";
}
public CaesarCipher(int s, String iT)
{
shift = s;
inputText = iT;
}
public void alphabet()
{
arr = new ArrayList<String>();
arr.add("A");
arr.add("B");
arr.add("C");
arr.add("D");
arr.add("E");
arr.add("F");
arr.add("G");
arr.add("H");
arr.add("I");
arr.add("J");
arr.add("K");
arr.add("L");
arr.add("M");
arr.add("N");
arr.add("O");
arr.add("P");
arr.add("Q");
arr.add("R");
arr.add("S");
arr.add("T");
arr.add("U");
arr.add("V");
arr.add("W");
arr.add("X");
arr.add("Y");
arr.add("Z");
}
public void convert()
{
String revisedText = inputText.replaceAll("\\s","");
//Turn revisedText into an array and match it with array above
revisedText.toUpperCase();
int j = 1;
String letter = "";
for (int i = 0; i < revisedText.length(); i++)
{
exchange.add(revisedText.substring(i, j));
j++;
}
}
public void shift()
{
shift = shift % 26 + 26;
ArrayList<String> newArr = new ArrayList<String>(); // array with shifted values
int pos = 0;
for(int r = 0; r < exchange.size(); r++)
{
if(arr.get(r).equals(exchange.get(r)))
arr.indexOf(r) + shift = pos;
}
}
public String toString()
{
return "";
}
}
Here is quick for loop for an example
String string = "Hello World";
String newPhrase = "";
int shift = 1;
for(int i = 0; i < string.length(); i++){
if(string.charAt(i) != ' ')
newPhrase += (char)(string.charAt(i) + shift);
else
newPhrase += ' ';
}
System.out.println(string + " -> " + newPhrase);
Output
Hello World -> Ifmmp Xpsme
However you should note that there are a couple edge cases i am not checking for. Once you understand the above code you should be able to find the edge cases I am talking about.

Java - make new string based on old one and lag

I need to get a new string based on an old one and a lag. Basically, I have a string with the alphabet (s = "abc...xyz") and based on a lag (i.e. 3), the new string should replace the characters in a string I type with the character placed some positions forward (lag). If, let's say, I type "cde" as my string, the output should be "fgh". If any other character is added in the string (apart from space - " "), it should be removed. Here is what I tried, but it doesn't work :
String code = "abcdefghijklmnopqrstuvwxyzabcd"; //my lag is 4 and I added the first 4 characters to
char old; //avoid OutOfRange issues
char nou;
for (int i = 0; i < code.length() - lag; ++i)
{
old = code.charAt(i);
//System.out.print(old + " ");
nou = code.charAt(i + lag);
//System.out.println(nou + " ");
// if (s.indexOf(old) != 0)
// {
s = s.replace(old, nou);
// }
}
I commented the outputs for old and nou (new, but is reserved word) because I have used them only to test if the code from position i to i + lag is working (and it is), but if I uncomment the if statement, it doesn't do anything and I leave it like this, it keeps executing the instructions inside the for statmement for code.length() times, but my string doesn't need to be so long. I have also tried to make the for statement like below, but I got lost.
for (int i = 0; i < s.length(); ++i)
{
....
}
Could you help me with this? Or maybe some advices about how I should think the algorithm?
Thanks!
It doesn't work because, as the javadoc of replace() says:
Returns a new string resulting from replacing all occurrences of oldChar in this string with newChar.
(emphasis mine)
So, the first time you meet an 'a' in the string, you replace all the 'a's by 'd'. But then you go to the next char, and if it's a 'd' that was an 'a' before, you replace it once again, etc. etc.
You shouldn't use replace() at all. Instead, you should simply build a new string, using a StringBuilder, by appending each shifted character of the original string:
String dictionary = "abcdefghijklmnopqrstuvwxyz";
StringBuilder sb = new StringBuilder(input.length());
for (int i = 0; i < input.length(); i++) {
char oldChar = input.charAt(i);
int oldCharPositionInDictionary = dictionary.indexOf(oldChar);
if (oldCharPositionInDictionary >= 0) {
int newCharPositionInDictionary =
(oldCharPositionInDictionary + lag) % dictionary.length();
sb.append(dictionary.charAt(newCharPositionInDictionary));
}
else if (oldChar == ' ') {
sb.append(' ');
}
}
String result = sb.toString();
Try this:
Convert the string to char array.
iterate over each char array and change the char by adding lag
create new String just once (instead of loop) with new String passing char array.
String code = "abcdefghijklmnopqrstuvwxyzabcd";
String s = "abcdef";
char[] ch = s.toCharArray();
char[] codes = code.toCharArray();
for (int i = 0; i < ch.length; ++i)
{
ch[i] = codes[ch[i] - 'a' + 3];
}
String str = new String(ch);
System.out.println(str);
}
My answer is something like this.
It returns one more index to every character.
It reverses every String.
Have a good day!
package org.owls.sof;
import java.util.Scanner;
public class Main {
private static final String CODE = "abcdefghijklmnopqrstuvwxyz"; //my lag is 4 and I added the first 4 characters to
#SuppressWarnings("resource")
public static void main(String[] args) {
System.out.print("insert alphabet >> ");
Scanner scanner = new Scanner(System.in);
String s = scanner.next();
char[] char_arr = s.toCharArray();
for(int i = 0; i < char_arr.length; i++){
int order = CODE.indexOf(char_arr[i]) + 1;
if(order%CODE.length() == 0){
char_arr[i] = CODE.charAt(0);
}else{
char_arr[i] = CODE.charAt(order);
}
}
System.out.println(new String(char_arr));
//reverse
System.out.println(reverse(new String(char_arr)));
}
private static String reverse (String str) {
char[] char_arr = str.toCharArray();
for(int i = 0; i < char_arr.length/2; i++){
char tmp = char_arr[i];
char_arr[i] = char_arr[char_arr.length - i - 1];
char_arr[char_arr.length - i - 1] = tmp;
}
return new String(char_arr);
}
}
String alpha = "abcdefghijklmnopqrstuvwxyzabcd"; // alphabet
int N = alpha.length();
int lag = 3; // shift value
String s = "cde"; // input
StringBuilder sb = new StringBuilder();
for (int i = 0, index; i < s.length(); i++) {
index = s.charAt(i) - 'a';
sb.append(alpha.charAt((index + lag) % N));
}
String op = sb.toString(); // output

Scrambling strings multiple times in eclipse

I'm having some trouble with some code for a program I'm writing. The purpose of this program is to take a word from a separate text file, scramble it ten times, and display the scrambled letters of the word. The problem that I'm having is that I'm unsure as to how I would go about scrambling the letters ten times. I know that the actual scrambling takes place in my mixer method but the how eludes me. I thought about using a for loop but I'm not sure how to go about it.
import java.io.*;
import java.util.*;
public class Scrambler {
public static void main(String[] args) throws FileNotFoundException {
Scanner input = new Scanner(new File("words.txt"));
String text = input.next();
System.out.println("Original Word: " + text);
System.out.println();
System.out.println("Scrambled Word:");
System.out.println("********");
separate(text);
System.out.println("********");
}
public static void separate(String text) {
System.out
.println(" " + text.charAt(0) + " " + text.charAt(1) + " ");
System.out.println(text.charAt(2) + " " + text.charAt(3));
System.out
.println(" " + text.charAt(4) + " " + text.charAt(5) + " ");
}
public static String mixer(String text) {
Random r = new Random();
int r1 = r.nextInt(text.length());
int r2 = r.nextInt(text.length());
String a = text.substring(0, r1);
char b = text.charAt(r1);
String c = text.substring(r1 + 1, r2);
char d = text.charAt(r2);
String e = text.substring(r2 + 1, text.length());
text = a + b + c + d + e;
return text;
}
}
Your mixer() is not working properly. I would first make the string into an char[], and then retrieve 2 random indices and switch the characters in these indices.
char[] stringasarray = text.toCharArray();
int length = text.length;
for(int i=0; i<length; i++){
int letter1 = rnd.nextInt(length);
int letter2 = rnd.nextInt(length);
char temp = stringasarray[letter1];
stringasarray[letter1] = stringasarray[letter2];
stringasarray[letter2] = temp;
}
String newtext = new String(stringasarray);
A simple for loop would do it:
String word = "Hello World";
for(int i = 0; i < 10; i++){
word = mixer(word);
}
Here is one approach for scrambling the string(s) ten times;
// Passing in the Random.
public static String mixer(String in, Random rnd) {
StringBuilder sb = new StringBuilder();
if (in != null) { // <-- check for null.
List<Character> chars = new ArrayList<Character>();
for (char ch : in.toCharArray()) {
chars.add(ch); // <-- add each character to the List.
}
Collections.shuffle(chars, rnd); // <-- "scramble"
for (char ch : chars) {
sb.append(ch);
}
}
return sb.toString();
}
public static void main(String[] args) {
String t = "Hello";
Random rnd = new Random();
// I'm not sure why you want to do it 10 times, but here is one way.
for (int i =0; i < 10; i++) {
t = mixer(t, rnd); // <-- call mixer function.
}
System.out.println(t);
}
public static String mixer(String text) {
Random r = new Random();
int r1 = r.nextInt(text.length()); // generates a random number from 0 to text.length - 1
int r2 = r.nextInt(text.length()); //generates a random number from 0 to text.length - 1
String a = text.substring(0, r1); // creates a substring containing characters from 0 to r1
char b = text.charAt(r1); //grabs the character at r1
String c = text.substring(r1 + 1, r2); // creates a substring from r1+1 to r2
char d = text.charAt(r2); // grabs the character at r2
String e = text.substring(r2 + 1, text.length()); // grabs any remaining characters
text = a + b + c + d + e; // recombines them
return text;
}
without delving into how substring works, this would most likely return the exact same string. If you changed the order of a + b + c + d + e it would scramble it. It takes the word and divides it into five pieces, then reassembles it.
It could probably use a lot of error checking, however, and some validation.

Fancy looping in Java

I have a problem wherein I have two strings, the length of one of which I will know only upon execution of my function. I want to write my function such that it would take these two stings and based upon which one is longer, compute a final string as under -
finalString = longerStringChars1AND2
+ shorterStringChar1
+ longerStringChars3and4
+ shorterStringChar2
+ longerStringChars5AND6
...and so on till the time the SHORTER STRING ENDS.
Once the shorter string ends, I want to append the remaining characters of the longer string to the final string, and exit. I have written some code, but there is too much looping for my liking. Any suggestions?
Here is the code I wrote - very basic -
public static byte [] generateStringToConvert(String a, String b){
(String b's length is always known to be 14.)
StringBuffer stringToConvert = new StringBuffer();
int longer = (a.length()>14) ? a.length() : 14;
int shorter = (longer > 14) ? 14 : a.length();
int iteratorForLonger = 0;
int iteratorForShorter = 0;
while(iteratorForLonger < longer) {
int count = 2;
while(count>0){
stringToConvert.append(b.charAt(iteratorForLonger));
iteratorForLonger++;
count--;
}
if(iteratorForShorter < shorter && iteratorForLonger >= longer){
iteratorForLonger = 0;
}
if(iteratorForShorter<shorter){
stringToConvert.append(a.charAt(iteratorForShorter));
iteratorForShorter++;
}
else{
break;
}
}
if(stringToConvert.length()<32 | iteratorForLonger<b.length()){
String remainingString = b.substring(iteratorForLonger);
stringToConvert.append(remainingString);
}
System.out.println(stringToConvert);
return stringToConvert.toString().getBytes();
}
You can use StringBuilder to achieve this. Please find below source code.
public static void main(String[] args) throws InterruptedException {
int MAX_ALLOWED_LENGTH = 14;
String str1 = "yyyyyyyyyyyyyyyy";
String str2 = "xxxxxx";
StringBuilder builder = new StringBuilder(MAX_ALLOWED_LENGTH);
builder.append(str1);
char[] shortChar = str2.toCharArray();
int index = 2;
for (int charCount = 0; charCount < shortChar.length;) {
if (index < builder.length()) {
// insert 1 character from short string to long string
builder.insert(index, shortChar, charCount, 1);
}
// 2+1 as insertion index is increased after after insertion
index = index + 3;
charCount = charCount + 1;
}
String trimmedString = builder.substring(0, MAX_ALLOWED_LENGTH);
System.out.println(trimmedString);
}
Output
yyxyyxyyxyyxyy
String one = "longwordorsomething";
String two = "short";
String shortString = "";
String longString = "";
if(one.length() > two.length()) {
shortString = two;
longString = one;
} else {
shortString = one;
longString = two;
}
StringBuilder newString = new StringBuilder();
int j = 0;
for(int i = 0; i < shortString.length(); i++) {
if((j + 2) < longString.length()) {
newString.append(longString.substring(j, j + 2));
j += 2;
}
newString.append(shortString.substring(i, i + 1));
}
// Append last part
newString.append(longString.substring(j));
System.out.println(newString);

Categories

Resources