How can I get the longest increasing subsequence in a string? - java

I'm pretty rusty on my Java skills but I was trying to write a program that prompts the user to enter a string and displays a maximum length increasing ordered subsequence of characters. For example, if the user entered Welcome the program would output Welo. If the user entered WWWWelllcommmeee, the program would still output Welo. I've gotten this much done but it's not doing what it should be and I'm honestly at a loss as to why.
import java.util.ArrayList;
import java.util.Scanner;
public class Stuff {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.println("Please enter a string. ");
String userString = input.next();
ArrayList charList = new ArrayList();
ArrayList finalList = new ArrayList();
int currentLength = 0;
int max = 0;
for(int i = 0; i < userString.length(); i++){
charList.add(userString.charAt(i));
for(int j = i; j < userString.length(); j++){
int k=j+1;
if(k < userString.length() && userString.charAt(k) > userString.charAt(j)){
charList.add(userString.charAt(j));
currentLength++;
}
}
}
if(max < currentLength){
max = currentLength;
finalList.addAll(charList);
}
for (int i = 0; i < finalList.size(); i++){
char item = (char) finalList.get(i);
System.out.print(item);
}
int size1 = charList.size();
int size2 = finalList.size();
System.out.println("");
System.out.println("Size 1 is: " + size1 + " Size 2 is : " + size2);
}
}
My code, if I input Welcome, outputs WWeceeclcccome.
Does anyone have some tips on what I'm doing wrong?

In these cases it tends to help to step away from the keyboard and think about the algorithm you're trying to implement. Try to explain it first in words.
You are constructing a list of individual characters by appending each of the characters in the input string followed by characters to its right that are in correct alphabetical with their successor. For the input "Welcome" this means the accumulated output will be, showing the outer loop in vertical and inner loop in horizontal:
W W e c
e e c
l c
c c
o
m
e
In total: WWeceeclccome

I can't see the logic of this implementation. Here is a faster solution which runs in O(nlogn) time.
import java.util.Scanner;
public class Stuff
{
//return the index of the first element that's not less than the target element
public static int bsearch(char[] arr, int size, int key)
{
int left = 0;
int right = size - 1;
int mid;
while (left <= right)
{
mid = (left + right) / 2;
if(arr[mid] < key)
left = mid + 1;
else
right = mid - 1;
}
return left;
}
public static void main(String[] args)
{
Scanner input = new Scanner(System.in);
System.out.println("Please enter a string: ");
String userString = input.next();
char[] maxArr = new char[userString.length()];
char[] precedent = new char[userString.length()];
maxArr[0] = userString.charAt(0);
precedent[0] = userString.charAt(0);
int len = 1;
for(int i = 1; i < userString.length(); i++)
{
if(userString.charAt(i) > maxArr[len - 1])
{
maxArr[len] = userString.charAt(i);
precedent[len] = userString.charAt(i);
len++;
}
else
maxArr[bsearch(maxArr, len, userString.charAt(i))] = userString.charAt(i);
}
//System.out.println(len);
for(int i = 0; i < len; i++)
System.out.print(precedent[i]);
}
}

Using Dynamic Programming O(N^2) in lexicography order mean if i/p is abcbcbcd then o/p can be abcccd, abbbcd, abbccd but as per lexicography order o/p will be abbbcd.
public static String longestIncreasingSubsequence(String input1) {
int dp[] = new int[input1.length()];
int i,j,max = 0;
StringBuilder str = new StringBuilder();
/* Initialize LIS values for all indexes */
for ( i = 0; i < input1.length(); i++ )
dp[i] = 1;
/* Compute optimized LIS values in bottom up manner */
for ( i = 1; i < input1.length(); i++ )
for ( j = 0; j < i; j++ )
if (input1.charAt(i) >= input1.charAt(j) && dp[i] < dp[j]+1)
dp[i] = dp[j] + 1;
/* Pick maximum of all LIS values */
for ( i = 0; i < input1.length(); i++ ) {
if ( max < dp[i] ) {
max = dp[i];
if (i + 1 < input1.length() && max == dp[i+1] && input1.charAt(i+1) < input1.charAt(i)) {
str.append(input1.charAt(i+1));
i++;
} else {
str.append(input1.charAt(i));
}
}
}
return str.toString();
}

Related

Google Kickstart 2021 Round A - K Goodness

I have been trying to submit my code, but I am getting Runtime Error everytime. I am not able to point out the problem with my code. The code works fine on my computer, it just shows RUNTIME ERROR when I try to submit it.
I coded in IntelliJ.
import java.util.Scanner;
class practice2 {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
int t = 0;
do {
t = input.nextInt(); // number of test cases
} while (t < 1 || t > 100);
int n = 0; // variable to store length of the string
int k = 0; // variable to store the goodness number
String s = "";
for (int i = 0; i < t; i++) {
do {
n = input.nextInt(); // string length
} while (n < 1 || n > 100);
do {
k = input.nextInt(); // goodness number
} while (k < 0 || k > (n / 2));
input.nextLine(); // clearing buffer
do {
s = input.nextLine();
} while (s.length() != n);
s = s.toUpperCase(); // in uppercase
int minOp = checkGoodness(s, k, n);
System.out.println("case #" + (i + 1) + ": " + minOp);
}
}
public static int checkGoodness(String s, int k, int n) {
char[] sArr = new char[s.length()];
sArr = s.toCharArray();
int score = 0; int minOp = 0;
for (int i = 0; i < sArr.length / 2; i++) {
if (sArr[i] != sArr[sArr.length - i - 1]) {
score++;
}
}
if ( score == k)
minOp = 0;
else
minOp = Math.abs(score - k);
return minOp;
}
}
Make your class public and change it's name from "practice2" to "Solution".
The most frequent runtime errors with submitting to an online judge are the incorrect name of the main class. You should check the requirements for Java and see what name for the main class should you use. Change "practice2" to that and it should work.
Instead of
s = input.nextLine();
Try
s = input.next();
#include <bits/stdc++.h>
using namespace std;
int main() {
int t;
cin>>t;
for(int i=0;i<t;i++)
{
int n,m;
string s;
int c=0;
cin>>n>>m;
int j=n-1;
cin>>s;
for(int k=0;k<n/2 && j>=0 ; k++)
{
if(s[k]!=s[j] )
{
c++;
}
j--;
}
cout<<"Case #"<<i<<": "<<abs(m-c);
cout<<endl;
}
}

Maximum Integer Value java

I was trying to solve the Maximum Integer Value problem form Geeksforgeeks.
The problem states the following:
Given a string S of digits(0-9), your task is to find the maximum value that can be obtained from the string by putting either '*' or '+' operators in between the digits while traversing from left to right of the string and picking up a single digit at a time.
Input:
The first line of input contains T denoting the number of testcases. T testcases follow. Each testcase contains one line of input denoting the string.
Output:
For each testcase, print the maximum value obtained.
this is what I did:
class GFG
{
public static void sort(int[] numbers)
{
int n = numbers.length;
for (int i = 1; i < n; ++i)
{
int key = numbers[i];
int j = i - 1;
while (j >= 0 && numbers[j] > key)
{
numbers[j + 1] = numbers[j];
j = j -1 ;
}
numbers[j + 1] = key;
}
System.out.println(numbers.length - 1);
}
public static void main (String[] args)
{
Scanner sc = new Scanner(System.in);
int testCases = sc.nextInt();
int [] maxNum;
for(int i = 0; i< testCases; i++)
{
String numbers = sc.nextLine();
char[] cNumbers = numbers.toCharArray();
maxNum = new int [cNumbers.length];
for(int j = 0; j + 1 < cNumbers.length; j++)
{
int sum = 0;
int mult = 0;
sum = cNumbers[j] + cNumbers[j + 1];
mult = cNumbers[j] * cNumbers[j + 1];
int maxNumber = Math.max(sum, mult);
maxNum[i] = maxNumber;
}
sort(maxNum);
}
}
}
an example of Input:
2
01230
891
My Output:
-1
4
Correct Output:
9
73
What is wrong with my code?!
Just quick glance it would seem if your digit is less than two it should be added. 2 or larger should get multiplied. Not at a PC to test though.
The idea is to put the operators alternatively and choose the maximum results.
import java.util.Scanner;
public class Demo {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int testCases = Integer.parseInt(sc.nextLine());
for (int i = 0; i < testCases; i++) {
String numbers = sc.nextLine();
int max = 0;
for (int j = 0; j + 1 < numbers.length(); j++) {
int next = Integer.parseInt(numbers.substring(j, j+1));
if (max + next > max * next)
max = max + next;
else
max = max * next;
}
System.out.println(max);
}
sc.close();
}
}
After the execution of
int testCases = sc.nextInt();
the buffer contains a new line character. So when executing the line
String numbers = sc.nextLine();
it read '\n' into numbers, so you got -1 as the first output.
Also you need to convert character to Integer before using it any arithmetic operations.
sum = cNumbers[j] + cNumbers[j+1];
mult = cNumbers[j] * cNumbers[j+1];
So the above code will give you wrong results.
I tried the following sample and worked.
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String inputAsString = sc.nextLine();
int testCases = Integer.parseInt(inputAsString);
int maxNumber = 0;
for (int i = 0; i < testCases; i++) {
String numbers = sc.nextLine();
if(!numbers.matches("\\d+")){
System.out.println("Only numeric values are expected.");
continue;
}
char[] cNumbers = numbers.toCharArray();
int sum = 0;
int mult = 1;
for (int j = 0; j < cNumbers.length; j++) {
int nextNumber = Character.getNumericValue(cNumbers[j]);
sum = sum + nextNumber;
mult = mult * nextNumber;
maxNumber = mult > sum ? mult : sum;
sum = maxNumber;
mult = maxNumber;
}
System.out.println(maxNumber);
}
sc.close();
}
I read your description and what you do is wrong. please read question carefully specially the example in reference site.
as mentioned in comments by moilejter you use sc.nextInt() which doesn't read '\n' and make problem. the next sc.nextLine() will read only a empty string and your program throw exception.
Second problem is that you must calculate max continuously and you don't need an int array (you calculate max result of operation between two successive number and save them in an array which is not correspond to max integer value. you only find max between each two digit but not max of operation on all digit).
Third problem is that you use character as numbers which is made incorrect result. (you must convert them to integer)
So there is a code that works for your output:
public class GFG
{
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int testCases = Integer.valueOf(sc.nextLine());
for (int i = 0; i < testCases; i++)
{
String numbers = sc.nextLine();
char[] cNumbers = numbers.toCharArray();
long maxUntilNow = cNumbers[0] - '0';
for (int j = 1; j < cNumbers.length; j++)
{
int numberOfThisPlace = cNumbers[j] - '0';
maxUntilNow = Math.max(maxUntilNow + numberOfThisPlace,
maxUntilNow * numberOfThisPlace);
}
System.out.println(maxUntilNow);
}
}
}
I hope this is what you want.
As per the problem statement, we need to obtain maximum value from the string by putting either * or + operators in between the digits while traversing from left to right of the string and picking up a single digit at a time.
So, this can be solved in O(n) without using any sorting algorithm.
The simple logic behind the solution is whenever you find "0" or "1" in any of the operands use "+" and the rest of the places use "*".
Here is my solution which got successfully submitted:
import java.util.*;
import java.lang.*;
import java.io.*;
class GFG {
public static void main (String[] args) {
Scanner scan = new Scanner(System.in);
int T = Integer.parseInt(scan.nextLine());
while(T-- > 0) {
String str = scan.nextLine();
maxValue(str);
}
}
static void maxValue(String str) {
long maxNumber = 0;
for(int i = 0; i < str.length(); i++) {
int n = Character.getNumericValue(str.charAt(i));
if (maxNumber == 0 || maxNumber == 1 ||
n == 0 || n == 1) {
maxNumber += n;
} else {
maxNumber *= n;
}
}
System.out.println(maxNumber);
}
}

Even after using a global static array my values of the array are changing in java. How to overcome it?

In this code I am having some problem as I have marked using a loop which is printing some values. I am storing them in an array as mentioned and am trying to print the values in another function. But even after using the global array the value of the array is changing.
I am not able to figure out the problem. Please help me out.
import java.io.*;
import java.util.*;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
// Java program to print all permutations of a
// given string.
public class test3
{
static int[] val = new int[100] ; //array declaration as global
public static void main(String[] args)
{
System.out.println("An incremented value");
for(int i=2;i<=2;i++) {
String p="";
for(int j=0;j<=i;j++) {
for(int m=0;m<j;m++) {
p=p+"&";
}
for(int m=0;m<i-j;m++) {
p=p+"|";
}
printAllPermutations(p);
p="";
}
}
System.out.println();
for(int xy=0;xy<32;xy++)
System.out.print("["+xy+"]"+"="+val[xy]+" "); //trying to print the array
}
static void print(char[] temp) {
String a="";
System.out.println();
for (int i = 0; i < temp.length; i++)
{ System.out.print(temp[i]);
a=a+temp[i];}
System.out.print(" "+"opr:"+temp.length+" ");
final int N = temp.length+1;
/*===================CODE PROBLEM PART START=======================*/
for (int i = 0; i < (1 << N); i++) {
// System.out.println(zeroPad(Integer.toBinaryString(i), N));
String b=zeroPad(Integer.toBinaryString(i), N)+"";
// System.out.println("a: "+a+" b:"+b);
char[] arrayA = b.toCharArray();
char[] arrayB = a.toCharArray();
StringBuilder sb = new StringBuilder();
int ii = 0;
while( ii < arrayA.length && ii < arrayB.length){
sb.append(arrayA[ii]).append(arrayB[ii]);
++ii;
}
for(int j = ii; j < arrayA.length; ++j){
sb.append(arrayA[j]);
}
for(int j = ii; j < arrayB.length; ++j){
sb.append(arrayB[j]);
}
//System.out.println(sb.toString());
try {
ScriptEngineManager sem = new ScriptEngineManager();
ScriptEngine se = sem.getEngineByName("JavaScript");
String myExpression = sb.toString();
// System.out.print(se.eval(myExpression));
val[i]=(int)(se.eval(myExpression)); //inserting array value
System.out.print(val[i]); //NEED TO HAVE THESE VALUES IN THE 1-D ARRAY
// System.out.print(val[i]);
} catch (ScriptException e) {
System.out.println("Invalid Expression");
e.printStackTrace();}
}
/*===================CODE PROBLEM PART END========================*/
//
}
//unchangable = rest of the function
static int factorial(int n) {
int f = 1;
for (int i = 1; i <= n; i++)
f = f * i;
return f;
}
static int calculateTotal(char[] temp, int n) {
int f = factorial(n);
// Building HashMap to store frequencies of
// all characters.
HashMap<Character, Integer> hm =
new HashMap<Character, Integer>();
for (int i = 0; i < temp.length; i++) {
if (hm.containsKey(temp[i]))
hm.put(temp[i], hm.get(temp[i]) + 1);
else
hm.put(temp[i], 1);
}
// Traversing hashmap and finding duplicate elements.
for (Map.Entry e : hm.entrySet()) {
Integer x = (Integer)e.getValue();
if (x > 1) {
int temp5 = factorial(x);
f = f / temp5;
}
}
return f;
}
static void nextPermutation(char[] temp) {
// Start traversing from the end and
// find position 'i-1' of the first character
// which is greater than its successor.
int i;
for (i = temp.length - 1; i > 0; i--)
if (temp[i] > temp[i - 1])
break;
// Finding smallest character after 'i-1' and
// greater than temp[i-1]
int min = i;
int j, x = temp[i - 1];
for (j = i + 1; j < temp.length; j++)
if ((temp[j] < temp[min]) && (temp[j] > x))
min = j;
// Swapping the above found characters.
char temp_to_swap;
temp_to_swap = temp[i - 1];
temp[i - 1] = temp[min];
temp[min] = temp_to_swap;
// Sort all digits from position next to 'i-1'
// to end of the string.
Arrays.sort(temp, i, temp.length);
// Print the String
print(temp);
}
static void printAllPermutations(String s) {
// Sorting String
char temp[] = s.toCharArray();
Arrays.sort(temp);
// Print first permutation
print(temp);
// Finding the total permutations
int total = calculateTotal(temp, temp.length);
for (int i = 1; i < total; i++)
nextPermutation(temp);
}
static String zero(int L) {
return (L <= 0 ? "" : String.format("%0" + L + "d", 0));
}
static String zeroPad(String s, int L) {
return zero(L - s.length()) + s;
}
}
The output that I am getting is
An incremented value
|| opr:2 01111111 //WANT TO STORE THESE 32 VALUES IN 1 D ARRAY
&| opr:2 01010111 // AND PRINT THEM OUT
|& opr:2 00011111
&& opr:2 00000001
[0]=0 [1]=0 [2]=0 [3]=0 [4]=0 [5]=0 [6]=0 [7]=1 [8]=0 [9]=0 [10]=0 [11]=0 [12]=0 [13]=0 [14]=0 [15]=0 [16]=0 [17]=0 [18]=0 [19]=0 [20]=0 [21]=0 [22]=0 [23]=0 [24]=0 [25]=0 [26]=0 [27]=0 [28]=0 [29]=0 [30]=0 [31]=0
what I need to do is to store those 32 values in 1 D array for further operation but while doing it all the array values displays 0 only except [7]. I dont know whats going on here.
Reference types are not bound to local scopes, just because your array is static to the class it does not mean that changing the values in one function will not change the values in the actual array. The reference to your array as a parameter will be a copy, but the reference is still "pointing" on an actual object, which is not a copy bound to your local scope.
If you want to save two different states of the array, you will have to save them yourself.

Java set/setElementAt not setting the right value

I need to find all the permutations for a given n(user input) without backtracking.
What i tried is:
import java.util.Scanner;
import java.util.Vector;
class Main {
private static int n;
private static Vector<Vector<Integer>> permutations = new Vector<>();
private static void get_n() {
Scanner user = new Scanner(System.in);
System.out.print("n = ");
n = user.nextInt();
}
private static void display(Vector<Vector<Integer>> permutations) {
for (int i = 0; i < factorial(n) - 1; ++i) {
for (int j = 0; j < n; ++j) {
System.out.print(permutations.elementAt(i).elementAt(j) + " ");
}
System.out.println();
}
}
private static int factorial(int n) {
int result = 1;
for (int i = 1; i <= n; ++i) {
result *= i;
}
return result;
}
private static int max(Vector<Integer> permutation) {
int max = permutation.elementAt(0);
for (int i = 1; i < permutation.size(); ++i)
if (permutation.elementAt(i) > max)
max = permutation.elementAt(i);
return max;
}
// CHECKS FOR ELEMENT COUNT AND 0 - (n-1) APPARITION
public static int validate_permutation(Vector<Integer> permutation) {
// GOOD NUMBER OF ELEMENTS
if (max(permutation) != permutation.size() - 1)
return 0;
// PROPER ELEMENTS APPEAR
for (int i = 0; i < permutation.size(); ++i)
if (!permutation.contains(i))
return 0;
return 1;
}
private static Vector<Integer> next_permutation(Vector<Integer> permutation) {
int i;
do {
i = 1;
// INCREMENT LAST ELEMENT
permutation.set(permutation.size() - i, permutation.elementAt(permutation.size() - i) + 1);
// IN A P(n-1) PERMUTATION FOUND n. "OVERFLOW"
while (permutation.elementAt(permutation.size() - i) == permutation.size()) {
// RESET CURRENT POSITION
permutation.set(permutation.size() - i, 0);
// INCREMENT THE NEXT ONE
++i;
permutation.set(permutation.size() - i, permutation.elementAt(permutation.size() - i) + 1);
}
} while (validate_permutation(permutation) == 0);
// OUTPUT
System.out.print("output of next_permutation:\t\t");
for (int j = 0; j < permutation.size(); ++j)
System.out.print(permutation.elementAt(j) + " ");
System.out.println();
return permutation;
}
private static Vector<Vector<Integer>> permutations_of(int n) {
Vector<Vector<Integer>> permutations = new Vector<>();
// INITIALIZE PERMUTATION SET WITH 0
for (int i = 0; i < factorial(n); ++i) {
permutations.addElement(new Vector<>());
for(int j = 0; j < n; ++j)
permutations.elementAt(i).addElement(0);
}
for (int i = 0; i < n; ++i)
permutations.elementAt(0).set(i, i);
for (int i = 1; i < factorial(n); ++i) {
// ADD THE NEXT PERMUTATION TO THE SET
permutations.setElementAt(next_permutation(permutations.elementAt(i - 1)), i);
System.out.print("values set by permutations_of:\t");
for (int j = 0; j < permutations.elementAt(i).size(); ++j)
System.out.print(permutations.elementAt(i).elementAt(j) + " ");
System.out.println("\n");
}
System.out.print("\nFinal output of permutations_of:\n\n");
display(permutations);
return permutations;
}
public static void main(String[] args) {
get_n();
permutations.addAll(permutations_of(n));
}
}
Now, the problem is obvious when running the code. next_permutation outputs the correct permutations when called, the values are set correctly to the corresponding the vector of permutations, but the end result is a mass copy of the last permutation, which leads me to believe that every time a new permutation is outputted by next_permutation and set into the permutations vector, somehow that permutation is also copied over all of the other permutations. And I can't figure out why for the life of me.
I tried both set, setElementAt, and an implementation where I don't initialize the permutations vector fist, but add the permutations as they are outputted by next_permutation with add() and I hit the exact same problem. Is there some weird way in which Java handles memory? Or what would be the cause of this?
Thank you in advance!
permutations.setElementAt(next_permutation(permutations.elementAt(i - 1)), i);
This is literally setting the vector at permutations(i) to be the same object as permutations[i-1]. Not the same value - the exact same object. I think this the source of your problems. You instead need to copy the values in the vector.

why wont main recieve my returned int value java

so when I go to compile this Eclipse says, that the numbers for Insertionct and Shakerct are 0 and prints out a tie. I know for a fact that both methods are sorting correctly, but for some reason it doesn't return the amount of comparisons that they are making to main in order to decide which one sorted the array faster. Thanks for any help in advance.
import java.io.*;
import java.util.*;
public class Sorts {
private static Scanner in;
public static void main(String[] args) throws Exception {
in = new Scanner(System.in);
System.out.print("How many strings will you be entering? ");
int sz = Integer.parseInt (in.nextLine());
String[] A = new String[sz];
String[] B = new String[sz];
for (int i = 0; i < sz; i++){
System.out.print ("Enter String #"+(i+1)+": ");
A[i] = in.nextLine();// sets the array at i equal to a string
B[i] = A[i]; // sets array B to the same as array A so I can use it in the shaker sort method
}
int Insertionct = 0;
int Shakerct = 0;
System.out.println(Insertionct);
System.out.println(Shakerct);
if (Shakerct > Insertionct) {
System.out.println("Insertion Sort was faster!");
} else if (Shakerct < Insertionct) {
System.out.println("Shaker Sort was faster!");
} else {
System.out.println("It was a tie");
}
}
public static int InsertionSort (int Insertionct, String[] A) throws Exception { //sorts the array of strings with the insertion sort.
// initializes the count variable
int sz = A.length; // sets size equal toe array A
for (int i = 0; i < sz-1; i++)
for (int j = i; j >= 0 && A[j].compareTo (A[j+1]) > 0; j--) {
Insertionct++;
String t = A[j]; //switch A[j], A[j+1]
A[j] = A[j+1];
A[j+1] = t;
}
return Insertionct;
}
public static int ShakerSort (int Shakerct, String[] B) throws Exception {//Uses the ShakerSort in order to order the array.
int sz = B.length;
for (int i = 0; i < sz; i++){
int nsct = 0;
for(int j = nsct+sz-1; j > i; j--){//runs through the array backwards and then swaps if it needs to
Shakerct++;
if (B[j].compareTo(B[j-1]) < 0) {
nsct = 0;
String t = B[j];
B[j] = B[j-1];
B[j-1] = t;
} else {
nsct++; // if no swap happens it increases no swap to increment the starting points.
}
}
for (int j = nsct; j > sz-i-1; j++){
if (B[j].compareTo(B[j+1]) > 0){//runs through the array going forward swaps if needed
Shakerct++;
nsct = 0;
String t = B[j];
B[j] = B[j+1];
B[j+1] = t;
} else {
nsct++;// increases no-swap count if no swap happens and changes the starting point.
}
}
}
return Shakerct;
}
}
You don't call InsertionSort and ShakerSort in main.

Categories