My code keeps going out of bounds - java

I am trying to find all possible palindromes in a substring. I created a palindrome method which works but for some reason my code goes out of bounds instead of stopping after the last letter.
public static boolean palindrome(String input){
int i = input.length();
int k;
char[] palindrome_arr = new char[i];
char[] palindrome_arr1 = new char[i];
boolean result;
palindrome_arr = input.toCharArray();
for(k = 0; k<(i);k++)
{
// System.out.println(palindrome_arr[k]);
palindrome_arr1[k]=palindrome_arr[(palindrome_arr.length-1)-k];
//System.out.println(palindrome_arr1[k]);
// System.out.println(palindrome_arr[(palindrome_arr.length-1)-k]);
}
result = Arrays.equals(palindrome_arr, palindrome_arr1);//checks if its a //palindrome
if (result==true)
{
return true;
}
else
return false;
}
for (String sub11 : sub1) {
System.out.println(sub11);
String sub2;
sub2 = sub11;
for (int q = 0; q < sub2.length()-1; q++)
{
sub = sub2.substring(q, sub2.length()-q);
// System.out.println(sub);
If(sub.length() > 1){
if(palindrome(sub) == true){
System.out.println(sub);
counter++;
hm.put(counter, sub);
}
}
}

Your error is here.
sub = sub2.substring(q, sub2.length()-q);
For example, sub2.length is 5. And on the 4th iteration when q will be 3 and (sub2.length-q) is 2 and your values in the method will be sub2.substring(3, 2);
First value should not be greater than 2nd value, if it is greater then it will through the Out of bounds exception.
I gave you a basic idea, now change this code to make it fine.

Related

Palindrome in java

Here what I tried
sample input is "aabaa"
eg: in if condition val[0] = a[4]
if it is equal i stored it in counter variable if it is half of the length it original string it is palindrome
if it is not it is not a palindrome
I tried with my basic knowledge in java if there is any errors let me know
boolean solution(String inputString) {
int val = inputString.length();
int count = 0;
for (int i = 0; i<inputString.length(); i++) {
if(inputString.charAt(i) == inputString.charAt(val-i)) {
count = count++;
if (count>0) {
return true;
}
}
}
return true;
}
How about
public boolean isPalindrome(String text) {
String clean = text.replaceAll("\\s+", "").toLowerCase();
int length = clean.length();
int forward = 0;
int backward = length - 1;
while (backward > forward) {
char forwardChar = clean.charAt(forward++);
char backwardChar = clean.charAt(backward--);
if (forwardChar != backwardChar)
return false;
}
return true;
}
From here
In your version you compare first element with last, second with second last etc.
last element in this case is inputString.length()-1(so need to use 'inputString.charAt(val-i-1)' . If you iterate till end, then the count should be equal to length of the string.
for(int i = 0; i<inputString.length(); i++){
if(inputString.charAt(i) == inputString.charAt(val-i-1)){
count ++;
}
}
return (count==val); //true when count=val
Or alternatlively iterate till the mid point of the array, then count value is val/2.
for(int i = 0; i<inputString.length()/2; i++){
if(inputString.charAt(i) == inputString.charAt(val-i-1)){
count ++;
}
}
return (count==val/2); //true when count=val/2
There's no constraints in the question so let me throw in a more cheesy solution.
boolean isPalindrome(String in)
final String inl = in.toLowerCase();
return new StringBuilder(inl).reverse().toString().equals(inl);
}
A palindrome is a word, sentence, verse, or even a number that reads the same forward and backward. In this java solution, we’ll see how to figure out whether the number or the string is palindrome in nature or not.
Method - 1
class Main {
public static void main(String[] args) {
String str = "Nitin", revStr = "";
int strLen = str.length();
for (int i = (strLen - 1); i >=0; --i) {
revStr = revStr + str.charAt(i);
}
if (str.toLowerCase().equals(revStr.toLowerCase())) {
System.out.println(str + " is a Palindrome String.");
}
else {
System.out.println(str + " is not a Palindrome String.");
}
Method - 2
class Main {
public static void main(String[] args) {
int n = 3553, revNum = 0, rem;
// store the number to the original number
int orgNum = n;
/* get the reverse of original number
store it in variable */
while (n != 0) {
remainder = n % 10;
revNum = revNum * 10 + rem;
n /= 10;
}
// check if reversed number and original number are equal
if (orgNum == revNum) {
System.out.println(orgNum + " is Palindrome.");
}
else {
System.out.println(orgNum + " is not Palindrome.");
}

creating a list of palindrome numbers

I'm trying to create a List of palindrome numbers that made from the product of two 3-digit numbers but it is returning []. What am I doing wrong?
edit: I couldn't add the isPalindrome function initially cause stackoverflow would complain that "my post mostly code" Is there anything wrong with my isPalindrome function?
public class Solution {
//list of digit numbers of a number
ArrayList<Long> digits = new ArrayList<>();
//list of palindrome numbers
public ArrayList<Long> pal = new ArrayList<>();
// checks if the given number is a palindrome
boolean isPalindrome(long num) {
// creates list of digit numbers of a number
// ex. 12345 -> [5,4,3,2,1]
while(num > 0) {
long lastdigit = num % 10;
digits.add(lastdigit);
num = num / 10;
}
//checks if the number is a palindrome by checking the first and last index
// when the number of digits is even
if(digits.size() % 2 == 0) {
while(digits.size() > 0) {
int last = digits.size() - 1;
if (digits.get(0) == digits.get(last)) {
digits.remove(last);
digits.remove(0);
}
else {
return false;
}
}
return true;
}
// when the number of digits is odd
else while(digits.size() > 1) {
int last = digits.size() - 1;
if (digits.get(0) == digits.get(last)) {
digits.remove(last);
digits.remove(0);
}
else {
return false;
}
}
return true;
}
ArrayList<Long> findPal() {
for (long i = 100; i <= 999; i++) {
for (long j = 100; j <= 999; j++) {
Long product = i * j;
if (isPalindrome(product)) {
pal.add(product);
}
}
}
return pal;
}
public static void main(String[] args) {
Solution sol = new Solution();
System.out.println(sol.isPalindrome((long)121)); //true
System.out.println(sol.isPalindrome((long)12345)); // false
System.out.println(sol.findPal()); //[]
}
}
The problem is most likely in the isPalindrome method that you haven't shown us.
There are a couple of other problems:
The pal field should really be a local variable in the findPal method. (Hint: what happens if you call findPal() twice? Once you have found the bug in isPalindrome, try it ....)
The list of palindromic numbers that you create will most likely contain duplicates. For example, if 104 x 521 is a palindromic number, then 521 x 104 will be as well.
You must have a function in which after passing the number from the loops it should seperate the numbers to a single digit and should return true if the reverse is also true
For eg:
121 - >121%10 - >1
Then 121/10 -> 12
Similarly keep doing this till its modulus is not zero
Then multiply the highest number with (len of digit -1) like
1*100+2*10+1
If it is same then it is palindrome
I know its quite long but its the simplest thing!
Edit:
In isPalindrome() function
if (digits.get(0) == digits.get(last)) {
digits.remove(last);
digits.remove(0);
}
else {
return false;
}
Here in Else block you need to empty the digits list. that is the main problem that you are not emptying it.
I just use your code and just created my isPalindrome function and everything is working fine.
Have a look at this code.
public class Solution {
ArrayList<Long> digits = new ArrayList<>();
ArrayList<Long> pal = new ArrayList<>();
ArrayList<Long> findPal() {
for (long i = 100; i <= 999; i++) {
for (long j = 100; j <= 999; j++) {
Long product = i * j;
if (isPalindrome(product)) {
pal.add(product);
}
}
}
return pal;
}
public static void main(String[] args) {
Solution sol = new Solution();
System.out.println(sol.isPalindrome((long) 121)); // true
System.out.println(sol.isPalindrome((long) 12345)); // false
System.out.println(sol.findPal()); // []
}
private boolean isPalindrome(Long longValue) {
Long temp = longValue;
String tempLong = "";
while (temp != 0) {
tempLong = tempLong + temp % 10 + "";
temp = temp / 10;
}
return Long.parseLong(tempLong) == longValue;
}
}

Increasing number sequence in a string java

Problem: Check if the numbers in the string are in increasing order.
Return:
True -> If numbers are in increasing order.
False -> If numbers are not in increasing order.
The String sequence are :
CASE 1 :1234 (Easy) 1 <2<3<4 TRUE
CASE 2 :9101112 (Medium) 9<10<11<12 TRUE
CASE 3 :9991000 (Hard) 999<1000 TRUE
CASE 4 :10203 (Easy) 1<02<03 FALSE
(numbers cannot have 0 separated).
*IMPORTANT : THERE IS NO SPACES IN STRING THAT HAVE NUMBERS"
My Sample Code:
// converting string into array of numbers
String[] str = s.split("");
int[] numbers = new int[str.length];
int i = 0;
for (String a : str) {
numbers[i] = Integer.parseInt(a.trim());
i++;
}
for(int j=0;j<str.length;j++)
System.out.print(numbers[j]+" ");
//to verify whether they differ by 1 or not
int flag=0;
for(int j=0;j<numbers.length-1;j++){
int result=Integer.parseInt(numbers[j]+""+numbers[j+1]) ;
if(numbers[j]>=0 && numbers[j]<=8 && numbers[j+1]==numbers[j]+1){
flag=1;
}
else if(numbers[j]==9){
int res=Integer.parseInt(numbers[j+1]+""+numbers[j+2]) ;
if(res==numbers[j]+1)
flag=1;
}
else if(result>9){
//do something
}
}
This is the code I wrote ,but I cant understand how to perform for anything except one-digit-numbers ( Example one-digit number is 1234 but two-digit numbers are 121314). Can anyone have a solution to this problem?. Please share with me in comments with a sample code.
I'm gonna describe the solution for you, but you have to write the code.
You know that the input string is a sequence of increasing numbers, but you don't know how many digits is in the first number.
This means that you start by assuming it's 1 digit. If that fails, you try 2 digits, then 3, and so forth, until you've tried half the entire input length. You stop at half, because anything longer than half cannot have next number following it.
That if your outer loop, trying with length of first number from 1 and up.
In the loop, you extract the first number using substring(begin, end), and parse that into a number using Integer.parseInt(s). That is the first number of the sequence.
You then start another (inner) loop, incrementing that number by one at a time, formatting the number to text using Integer.toString(i), and check if the next N characters of the input (extracted using substring(begin, end)) matches. If it doesn't match, you exit inner loop, to make outer loop try with next larger initial number.
If all increasing numbers match exactly to the length of the input string, you found a good sequence.
This is code for the pseudo-code suggested by Andreas .Thanks for the help.
for (int a0 = 0; a0 < q; a0++) {
String s = in.next();
boolean flag = true;
for (int i = 1; i < s.length() / 2; i++) {
int first = Integer.parseInt(s.substring(0, i));
int k=1;
for (int j = i; j < s.length(); j++) {
if (Integer.toString(first + (k++)).equals(s.substring(j, j + i)))
flag = true;
else{
flag=false;
break;
}
}
if (flag)
System.out.println("YES");
else
System.out.println("NO");
}
I would suggest the following solution. This code generates all substrings of the input sequence, orders them based on their start index, and then checks whether there exists a path that leads from the start index to the end index on which all numbers that appear are ordered. However, I've noticed a mistake (I guess ?) in your example: 10203 should also evaluate to true because 10<203.
import java.util.*;
import java.util.stream.Collectors;
public class PlayGround {
private static class Entry {
public Entry(int sidx, int eidx, int val) {
this.sidx = sidx;
this.eidx = eidx;
this.val = val;
}
public int sidx = 0;
public int eidx = 0;
public int val = 0;
#Override
public String toString(){
return String.valueOf(this.val);
}
}
public static void main(String[] args) {
assert(check("1234"));
assert(check("9101112"));
assert(check("9991000"));
assert(check("10203"));
}
private static boolean check(String seq) {
TreeMap<Integer,Set<Entry>> em = new TreeMap();
// compute all substrings of seq and put them into tree map
for(int i = 0; i < seq.length(); i++) {
for(int k = 1 ; k <= seq.length()-i; k++) {
String s = seq.substring(i,i+k);
if(s.startsWith("0")){
continue;
}
if(!em.containsKey(i))
em.put(i, new HashSet<>());
Entry e = new Entry(i, i+k, Integer.parseInt(s));
em.get(i).add(e);
}
}
if(em.size() <= 1)
return false;
Map.Entry<Integer,Set<Entry>> first = em.entrySet().iterator().next();
LinkedList<Entry> wlist = new LinkedList<>();
wlist.addAll(first.getValue().stream().filter(e -> e.eidx < seq
.length()).collect(Collectors.toSet()));
while(!wlist.isEmpty()) {
Entry e = wlist.pop();
if(e.eidx == seq.length()) {
return true;
}
int nidx = e.eidx + 1;
if(!em.containsKey(nidx))
continue;
wlist.addAll(em.get(nidx).stream().filter(n -> n.val > e.val).collect
(Collectors.toSet()));
}
return false;
}
}
Supposed the entered string is separated by spaces, then the code below as follows, because there is no way we can tell the difference if the number is entered as a whole number.
boolean increasing = true;
String string = "1 7 3 4"; // CHANGE NUMBERS
String strNumbers[] = string.split(" "); // separate by spaces.
for(int i = 0; i < strNumbers.length - 1; i++) {
// if current number is greater than the next number.
if(Integer.parseInt(strNumbers[i]) > Integer.parseInt(strNumbers[i + 1])) {
increasing = false;
break; // exit loop
}
}
if(increasing) System.out.println("TRUE");
else System.out.println("FALSE");

Java Loop - Removing numbers that has 4 or more of the same digits

I was wondering how one would create a loop where it would print all the numbers from 200000 - 900000 and remove all the digits such as 222244.
So far this is all I have:
import java.io.FileNotFoundException;
import java.io.PrintWriter;
public class alg {
public void algorithm(){
}
public static void main(String []args){
PrintWriter file = null;
try {
file = new PrintWriter("output.txt");
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
int x;
for (x = 200000; x < 900000; x++){
file.println(x);
}
}
file.close();
}
// return true if integer has 4 or more of same digit, otherwise false
static boolean check4(int i) {
int[] charCounts = new int[10];
for (char c : String.valueOf(i).toCharArray()) {
if (++charCounts[c-'0'] == 4) return true;
}
return false;
}
Since there are no mathematical solutions for this, you need to parse the numbers:
int x;
// loop through all the numbers
for (x = 200000; x < 900000; x++) {
// for each number x, check digits 0-9
for (int i = 0; i < 10; i ++) {
// convert current number x to a String
final String originalNumber = Integer.toString(x);
// replace all digits i in current number x and check if the lenth was decreased by 4 or more
if (originalNumber.replaceAll(Integer.toString(i)).length() <= originalNumber.length() - 4) {
// if so, print the current number x to your file
file.println(x);
}
}
}
I think there are better solutions but it should work.
I would suggest using java Pattern class with some kind of pattern like:
[0-9]{4}[0-9]{2}.
In loop you could just call String stringified = yourNumber + "";
and that match it with ALREADY compiled pattern.
Here's how I would do it. It is essentially a method to stringify the integer, break it into a Character[] and uses the Collections.frequency() method to check your condition. It will return true if the number has 4 or more of the same digit.
private static boolean containsFourOfSameDigit(Integer x) {
final int threshold = 4; //Change for 3, 2, whatever you want.
String s = x.toString();
/* Populate a char array and then list with all digits */
Character[] ch = new Character[s.length()];
for(int i = 0; i < s.length(); i++)
ch[i] = s.charAt(i);
ArrayList<Character> allDigits = new ArrayList<Character>(Arrays.asList(ch));
HashSet<Character> uniqueDigits = new HashSet<Character>(allDigits);
for(Character c : uniqueDigits)
if(Collections.frequency(allDigits, c) >= threshold)
return true;
return false;
}
System.out.println(containsFourOfSameDigit(200000)); will print true, as will your 222244 example. Note this doesn't complete your program, it is just the boolean method you are seeking.

How to search via character matching with a skip distance?

As the title says, I'm working on a project in which I'm searching a given text, moby dick in this case, for a key word. However instead of the word being linear, we are trying to find it via a skip distance ( instead of cat, looking for c---a---t).
I've tried multiple ways, yet can't seem to get it to actually finish one skip distance, have it not work, and call the next allowed distance (incrementing by 1 until a preset limit is reached)
The following is the current method in which this search is done, perhaps this is just something silly that I'm missing?
private int[] search()
throws IOException
{
/*
tlength is the text file length,
plength is the length of the
pattern word (cat in the original post),
text[] is a character array of the text file.
*/
int i=0, j;
int match[] = new int[2];
int skipDist = 2;
while(skipDist <= 100)
{
while(i<=tlength-(plength * skipDist))
{
j=plength-1;
while(j>=0 && pattern[j]==text[i+(j * skipDist)])j--;
if (j<0)
{
match[0] = skipDist;
match[1] = i;
return match;
}
else
{
i++;
}
}
skipDist = skipDist + 1;
}
System.out.println("There was no match!");
System.exit(0);
return match;
}
I do not know about the method you posted, but you can use this instead. I've used string and char array for this:
public boolean checkString (String s)
{
char[] check = {'c','a','t'};
int skipDistance = 2;
for(int i = 0; i< (s.length() - (skipDistance*(check.length-1))); i++)
{
boolean checkValid = true;
for(int j = 0; j<check.length; j++)
{
if(!(s.charAt(i + (j*skipDistance))==check[j]))
{
checkValid = false;
}
}
if(checkValid)
return true;
}
return false;
}
Feed the pattern to match in the char array 'check'.
String "adecrayt" evaluates true. String "cat" evaluates false.
Hope this helps.
[This part was for fixed skip distance]
+++++++++++++++++++++++++++
Now for any skip distance between 2 and 100:
public boolean checkString (String s)
{
char[] check = {'c','a','t'};
int index = 0;
int[] arr = new int[check.length];
for(int i = 0; i< (s.length()); i++)
{
if(check[index]==s.charAt(i))
{
arr[index++] = i;
}
}
boolean flag = true;
if(index==(check.length))
{
for(int i = 0; i<arr.length-1; i++)
{
int skip = arr[i+1]-arr[i];
if(!((skip>2)&&(skip<100)))
{
flag = false;
}
else
{
System.out.println("Skip Distance : "+skip);
}
}
}
else
{
flag = false;
}
return flag;
}
If you pass in a String, you only need one line:
public static String search(String s, int skipDist) {
return s.replaceAll(".*(c.{2," + skipDist + "}a.{2," + skipDist + "}t)?.*", "$1");
}
If no match found, a blank will be returned.

Categories

Resources