import java.util.Scanner;
public class POD9 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String tito_has = sc.nextLine();
String tito_wants = sc.nextLine();
String remaining = "";
int strips = 0;
while(true){
String longest_common = getLongestCommonSubstring(tito_has,tito_wants);
strips++;
tito_has = tito_has.replaceAll(longest_common,"*");
remaining = remaining + longest_common;
if(remaining.length() == tito_wants.length()){
break;
}
}
System.out.println(strips-1);
}
public static String getLongestCommonSubstring(String str1, String str2){
int m = str1.length();
int n = str2.length();
int max = 0;
int[][] dp = new int[m][n];
int endIndex=-1;
for(int i=0; i<m; i++){
for(int j=0; j<n; j++){
if(str1.charAt(i) == str2.charAt(j) && str1.charAt(i) != Character.valueOf('*'))
{
if(i==0 || j==0){
dp[i][j]=1;
}else{
dp[i][j] = dp[i-1][j-1]+1;
}
if(max < dp[i][j])
{
max = dp[i][j];
endIndex=i;
}
}
}
}
return str1.substring(endIndex-max+1,endIndex+1);
}
}
This is my code used to retrieve the minimum number of paper cuts that are needed to form string 2 from string 1. This is the solution to the problem: Paper Cut Problem
I approached the problem by finding the longest substring between what Tito wants and what he has.
Thereafter, I replace the found sequences with '' as the input will only have letters. Also, in the cases, say, it has: "abbap" and tito wants:"bbaap", then this gives 3 cuts a|bb|a|p and not
2 (found bb->remove it (cut 1)->got (aap) -> found aa(cut2)-> remove it-> found b). So using "" helps in not making wrong substrings match.
I am pretty sure that my approach will solve most of the test cases. But I am getting the TIMELIMIT error here.
Please help me find an optimum way to achieve this?
Related
So I made this to print primes between two numbers of my choice; however, it prints out a comma after the last number and I don't know how to take it off.
Example
in: 0 10
out: 2, 3, 5, 7,
I want 2,3,5,7
Scanner s = new Scanner(System.in);
int a = s.nextInt();
int b = s.nextInt();
for (int i = a; i <= b; i++){
int j;
for (j = 2; j<i; j++){
int p = i%j;
if(p==0){break;}
}
if(i == j){System.out.printf("%d,", i);}
}
}
Use a boolean to keep track of whether you've printed anything yet. Then your format string could be something like
anythingPrinted ? ",%d" : "%d"
That is, only include the comma in the format string if there's something printed.
Use a StringBuilder and write to the console at the end of your program.
StringBuilder sb = new StringBuilder();
for (int i = a; i <= b; i++){
int j;
for (j = 2; j<i; j++){
int p = i%j;
if(p==0){break;}
}
if(i == j){
// If the length of the StringBuilder is 0, no need for a comma
if(sb.length() != 0) {
sb.append(",");
}
sb.append(i);
}
}
System.out.println(sb);
This might seem like overkill, and for many cases it might be, but I have been writing a source code transcoder and I find this situation coming up a lot. Where I need commas in between values, or a prefix value which is only printed once. So I found it handy to create a class which simplifies things.
Again, you wouldn't probably want to use this if you code had one or two print loops in it, but maybe if you had more than a few. Perhaps you would remove in "on first" part if you were never going to use it.
public class FirstPrintOptions {
private PrintStream printStream;
private String onFirst;
private String remaining;
private boolean trip = false;
public FirstPrintOptions(PrintStream printStream, String onFirst, String remaining) {
this.printStream = printStream;
this.onFirst = onFirst;
this.remaining = remaining;
}
public void print() {
if (!trip) {
if (onFirst != null) {
printStream.print(onFirst);
}
trip = true;
} else {
if (remaining != null) {
printStream.print(remaining);
}
}
}
}
Then use it like this..
FirstPrintOptions firstPrintOptions = new FirstPrintOptions(System.out, null, ",");
for (int x=0;x<10;x++) {
firstPrintOptions.print();
System.out.print(x);
}
The results are..
0,1,2,3,4,5,6,7,8,9
I was testing and I came up with this. I was using compilejava.net so scanner doesn't work. I bypassed that part and just set a and b manually. Basically, it builds a string with the numbers and ends in a comma. Then it prints a substring including everything except the last comma.
import java.util.*;
public class HelloWorld {
public static void main(String[] args) {
//Scanner s = new Scanner(System.in);
int a = 2;
int b = 18;
String c = "Output = ";
for (int i = a; i <= b; i++){
int j;
for (j = 2; j<i; j++){
int p = i%j;
if(p==0){break;}
}
if(i == j){c=c+ Integer.toString(i) + ",";}
}
System.out.print(c.subSequence(0, c.length()-1));
}
}
this program for finding factors of a number
for(i=1;i<=number;i++)
{
if(number%i==0)
{
system.out.print(i);
if(i!=0)
{system.out.print(",");}
}
}
so i get the output for 10 as
1,2,5,10
I am learning Java and wonder how I can get two numbers in same line.
Is this algorithm is okay, what can I do improve? What can you suggest me?
import java.util.Scanner;
public class Main{
public static int Separate(String Values, int Order){
String toReturn = "";
int Counter = 0;
for(int Iterator = 0; Iterator < Values.length(); Iterator = Iterator + 1){
if(Values.charAt(Iterator) == ' ') {
if(Order == Counter) break;
else{
toReturn = "";
Counter = Counter + 1;
}
}
else toReturn += Values.charAt(Iterator);
}
return Integer.parseInt(toReturn);
}
public static void main(String[] args){
Scanner Entry = new Scanner(System.in);
System.out.print("Enter two numbers separated by space: ");
String Number = Entry.nextLine();
int Frst = Separate(Number, 0);
int Scnd = Separate(Number, 1);
}
}
what can I do improve? What can you suggest me?
Adopt the Java Naming Conventions:
Method Names are camelCase, starting with a lower case letter
Field and Property Names and Method Argument Names are camelCase, too
Basically only Class and Interface Names start with an upper case letter in Java.
public static int separate(String values, int order){
String toReturn = "";
int counter = 0;
for(int iterator = 0; ...) { ...
Else I'd say: This algorithm is pretty solid for a beginner. It's easy to understand what's going on.
Of course Java provides much more sophisticated tools to solve this, using for example Regular Expressions with myString.split(...), or Streams with IntStream intStream = myString.chars().
Last but not least you could add Exception Handling: What happens if Integer.parseInt is given some non-number? It will crash.
try {
return Integer.parseInt(toReturn);
} catch (NumberFormatException e) {
// when "toReturn" cannot be parsed to an int, return a
// default value instead of crashing your application
return 0;
}
Or if crashing is the desired behavior, or you can ensure that this method is never called with an illegal String, leave it as it is (= don't add try catch)
I think what you've done is great for well-formatted input, where you have a single space character between the numbers. As others have pointer out, following Java naming conventions will greatly improve the readability of your code.
Handling sequences of space characters, possible before, between, and after your numbers is a little tricky. The general pattern would be to consume any sequences of spaces, remember the current position, consume the sequence of digits, then if we're at the correct position return the parsed number.
public static int separate(String str, int order)
{
for(int i = 0, pos = 0; ; pos++)
{
while(i < str.length() && str.charAt(i) == ' ') i += 1;
int j = i;
while(i < str.length() && str.charAt(i) != ' ') i += 1;
if(i == j) throw new IllegalStateException("Missing number!");
if(order == pos)
{
// handle NumberFormatException
return Integer.parseInt(str.substring(j, i));
}
}
}
Test:
String s = " 23432 798 44";
for(int i=0; i<3; i++)
System.out.print(separate(s, i) + " ");
Output:
23432 798 44
I participated in a coding challenge on hackerearth , and i was asked the following question .
Alice and Bob are playing a game in which Bob gives a string SS of length NN consisting of lowercase English alphabets to Alice and ask her to calculate the number of sub-strings of this string which contains exactly 3 vowels.
This is my code
import java.io.BufferedReader;
import java.io.InputStreamReader;
class TestClass1{
public static void main(String args[] ) throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String line = br.readLine();
int N = Integer.parseInt(line);
String stringArray[]=new String[N];
for (int i = 0; i < N; i++) {
int len = Integer.parseInt(br.readLine());
stringArray[i]=br.readLine();
}
for (int i = 0; i < N; i++) {
System.out.println(determineNumberOfSubstring(stringArray[i]));
}
}
public static int determineNumberOfSubstring(String str)
{
int numberOfSubstring=0;
for(int i=0;i<str.length();i++)
{
int ctr=0;
for(int j=1;j<str.length()-i;j++)
{
String subString = str.substring(i,i+j);
if(subString.length()<3)
{
continue;
}
if(subString.contains("a")||subString.contains("e")||subString.contains("i")||subString.contains("o")||subString.contains("u")
||subString.contains("A")||subString.contains("E")||subString.contains("I")||subString.contains("O")||subString.contains("U"))
{
ctr+=3;
}
}
if(ctr==3){
numberOfSubstring++;
}
}
return numberOfSubstring;
}
}
Iam getting time limit exceeded for the above code . Could any one help me out on how to optimise it .
Update1
Code as per #GhostCat logic , this needs to be tested and is not the final code.
class TestClass1{
public static void main(String args[] ) throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String line = br.readLine();
int N = Integer.parseInt(line);
String stringArray[]=new String[N];
for (int i = 0; i < N; i++) {
int len = Integer.parseInt(br.readLine());
stringArray[i]=br.readLine();
}
for (int i = 0; i < N; i++) {
System.out.println(determineNumberOfSubstring(stringArray[i]));
}
}
public static int determineNumberOfSubstring(String str)
{
int numberOfSubstring=0;
int ctr=0;
int subStringStart=0;
Stack<String> s = new Stack<String>();
for(int i=0;i<str.length();i++)
{
if(isVowel(str.charAt(i)))
ctr++;
if(ctr==3)
{
numberOfSubstring++;
ctr=0;
if(s.empty())
s.push(str.substring(0,i));
else
s.push(new String(s.peek().substring(1,i+1)));
i=str.indexOf(s.peek().charAt(1))-1;
}
}
return numberOfSubstring;
}
private static boolean isVowel(char c) {
if(c=='a'||c=='e'||c=='i'||c=='o'||c=='u'
||c=='A'||c=='E'||c=='I'||c=='O'||c=='U')
return true;
return false;
}
}
Hint: your code is iterating the whole substring for each and any lower and upper case vowel there is. And that happens in a loop in a loop.
Instead: use ONE loop that goes over the characters of the input string. And then check each position if it is a vowel by checking against a set of characters (containing those valid vowels). The final thing you need: a simple "sliding" window; like: when you spot three vowels, you can increase your counter; to then "forget" about the first of the three vowels you just found; like in:
a x e y i --> vowels a/e/i give one substring
x e y i ... and you look out for the next substring e/i/... now
Actual implementation is left as exercise to the reader ...
Long story short: this count can be computed by processing your input ONCE. Your code is iterating countless times more than once. Well, not countless, but N * N * some more.
( the one thing to be careful with: when using a Set<Character> be precise when you turn a char value into aCharacter object; you want to minimize the instances of that happening, too; as that is a rather expensive operation )
HAPPY CODING ###### (if useful then upvote)
Que: count possible substring contain exactly 3 vowel in given string
my approach in O(n):
#include<bits/stdc++.h>
using namespace std;
int main()
{
string s;
cin>>s;
vector<long long int>idex;
idex.push_back(-1);
for(int i=0;i<n;i++)
{
if(s[i]=='a' || s[i]=='e' || s[i]=='i' || s[i]=='o' || s[i]=='u')
{
idex.push_back(i);
}
}
idex.push_back(n);
if(idex.size()<5)
{
cout<<0<<endl;
}
else
{
long long int ans=0;
for(int i=1;i<=idex.size()-4;i++)
{
ans+=(idex[i]-idex[i-1])*(idex[i+3]-idex[i+2]);
}
cout<<ans<<endl;
}
}
practice question part 1
practice question part 2
This is a practice question which is rather hard for me. Below is my code for the static method(the main method is fixed -unchangeable, and signature of static method is given), and my intention is to get the matches between the characters and print them out.
But there are some concerns:
1) How do i ensure it doesn't print when all the strings are aligned but there are extra characters which makes the boolean false and the result to be not aligned instead? (e.g amgk as second string & first string is Java Programming Course)
2) How do i make it print right? currently the spaces are off and the letters aren't what is wanted.
3) If there is more than one character a in str1, which do i choose to put, and how do i omit the rest when there is already a match?
Would really appreciate a pseudocode to help guide a beginner like me in solving this problem.
public class Q3 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.print("Enter the first string:");
String input1 = sc.nextLine();
System.out.print("Enter the second string:");
String input2 = sc.nextLine();
System.out.println();
if (matchStrings(input1, input2)) {
System.out.println();
System.out.println("There is an alignment as shown above.");
} else {
System.out.println("No alignment can be found.");
}
}
public static boolean matchStrings(String str1, String str2) {
// Modify the code below to return the correct value.
boolean isMatch = false;
//int firstChar = str2.charAt(0);
//int lastChar = str2.charAt(str2.length()-1);
int prevIndex = 0;
System.out.println(str1);
for (int j = 0; j< str2.length(); j++) {
for (int i = 0; i<str1.length();i++) {
char charToSearch = str1.charAt(i);
int newIndex = i;
if (str2.charAt(j)== charToSearch) {
for (int k = prevIndex; k < newIndex-1; k++) {
System.out.print(" ");
}
System.out.print(charToSearch);
//prevIndex=newIndex+1;
isMatch = true;
}
}
}
return isMatch;
}
}
I think two of the first few structures you learn in a Data Structures course is the stack and queue. Thus, I will provide an implementation using a Stack. You can use a Stack to store the test String and pop each char element off the stack when it is matched up with a character in the first string. Otherwise you would output an empty space " " in the matched String object:
Stack s2 = new Stack();
String str1 = "Java Programming";
String str2 = "amg";
for(int i = str2.length()-1; i >= 0; i--){ //Need to populate the stack backwards...LIFO
s2.push(str2.charAt(i));
}
String match = ""; //Used to store the matching line
for(int i = 0; i < str1.length(); i++){
if(str1.charAt(i) == (char)s2.peek()){
match += s2.pop().toString();
}
else
{
match += " ";
}
}
System.out.println(str1);
System.out.println(match);
You can also use a Queue for this, but I will leave that for you to learn on your own. Also practice on creating your own Stack object using arrays and integer pointers to handle overflow/underflow.
The above code would print out:
I'm trying to solve the string similarity question on interviewstreet.com. My code is working for 7/10 cases (and it is exceeding the time limit for the other 3).
Here's my code -
public class Solution {
public static void main(String[] args) {
Scanner user_input = new Scanner(System.in);
String v1 = user_input.next();
int number_cases = Integer.parseInt(v1);
String[] cases = new String[number_cases];
for(int i=0;i<number_cases;i++)
cases[i] = user_input.next();
for(int k=0;k<number_cases;k++){
int similarity = solve(cases[k]);
System.out.println(similarity);
}
}
static int solve(String sample){
int len=sample.length();
int sim=0;
for(int i=0;i<len;i++){
for(int j=i;j<len;j++){
if(sample.charAt(j-i)==sample.charAt(j))
sim++;
else
break;
}
}
return sim;
}
}
Here's the question -
For two strings A and B, we define the similarity of the strings to be the length of the longest prefix common to both strings. For example, the similarity of strings "abc" and "abd" is 2, while the similarity of strings "aaa" and "aaab" is 3.
Calculate the sum of similarities of a string S with each of it's suffixes.
Input:
The first line contains the number of test cases T. Each of the next T lines contains a string each.
Output:
Output T lines containing the answer for the corresponding test case.
Constraints:
1 <= T <= 10
The length of each string is at most 100000 and contains only lower case characters.
Sample Input:
2
ababaa
aa
Sample Output:
11
3
Explanation:
For the first case, the suffixes of the string are "ababaa", "babaa", "abaa", "baa", "aa" and "a". The similarities of each of these strings with the string "ababaa" are 6,0,3,0,1,1 respectively. Thus the answer is 6 + 0 + 3 + 0 + 1 + 1 = 11.
For the second case, the answer is 2 + 1 = 3.
How can I improve the running speed of the code. It becomes harder since the website does not provide a list of test cases it uses.
I used char[] instead of strings. It reduced the running time from 5.3 seconds to 4.7 seconds and for the test cases and it worked. Here's the code -
static int solve(String sample){
int len=sample.length();
char[] letters = sample.toCharArray();
int sim=0;
for(int i=0;i<len;i++){
for(int j=i;j<len;j++){
if(letters[j-i]==letters[j])
sim++;
else
break;
}
}
return sim;
}
used a different algorithm. run a loop for n times where n is equals to length the main string. for each loop generate all the suffix of the string starting for ith string and match it with the second string. when you find unmatched character break the loop add j's value to counter integer c.
import java.io.BufferedReader;
import java.io.InputStreamReader;
class Solution {
public static void main(String args[]) throws Exception {
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
int T = Integer.parseInt(in.readLine());
for (int i = 0; i < T; i++) {
String line = in.readLine();
System.out.println(count(line));
}
}
private static int count(String input) {
int c = 0, j;
char[] array = input.toCharArray();
int n = array.length;
for (int i = 0; i < n; i++) {
for (j = 0; j < n - i && i + j < n; j++)
if (array[i + j] != array[j])
break;
c+=j;
}
return c;
}
}
I spent some time to resolve this question, and here is an example of my code (it works for me, and pass thru all the test-cases):
static long stringSimilarity(String a) {
int len=a.length();
char[] letters = a.toCharArray();
char localChar = letters[0];
long sim=0;
int sameCharsRow = 0;
boolean isFirstTime = true;
for(int i=0;i<len;i++){
if (localChar == letters[i]) {
for(int j = i + sameCharsRow;j<len;j++){
if (isFirstTime && letters[j] == localChar) {
sameCharsRow++;
} else {
isFirstTime = false;
}
if(letters[j-i]==letters[j])
sim++;
else
break;
}
if (sameCharsRow > 0) {
sameCharsRow--;
sim += sameCharsRow;
}
isFirstTime = true;
}
}
return sim;
}
The point is that we need to speed up strings with the same content, and then we will have better performance with test cases 10 and 11.
Initialize sim with the length of the sample string and start the outer loop with 1 because we now in advance that the comparison of the sample string with itself will add its own length value to the result.
import java.util.Scanner;
public class StringSimilarity
{
public static void main(String args[])
{
Scanner user_input = new Scanner(System.in);
int count = Integer.parseInt(user_input.next());
char[] nextLine = user_input.next().toCharArray();
try
{
while(nextLine!= null )
{
int length = nextLine.length;
int suffixCount =length;
for(int i=1;i<length;i++)
{
int j =0;
int k=i;
for(;k<length && nextLine[k++] == nextLine[j++]; suffixCount++);
}
System.out.println(suffixCount);
if(--count < 0)
{
System.exit(0);
}
nextLine = user_input.next().toCharArray();
}
}
catch (Exception e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}