Question - You are given n strings w1, w2, ......, wn. Let Si denote the set of strings formed by considering all unique substrings of the string wi. A substring is defined as a contiguous sequence of one or more characters in the string. More information on substrings can be found here. Let S = {S1 U S2 U .... Sn} .i.e S is a set of strings formed by considering all the unique strings in all sets S1, S2, ..... Sn
My approach - I am using a TreeSet and filling it directly rather than creating a list, a set, and a sorted list.
import java.io.*;
import java.util.*;
import java.text.*;
import java.math.*;
import java.util.regex.*;
public class Solution
{
public static void main(String[] args)
{
Scanner in = new Scanner(System.in);
int cases = Integer.parseInt(in.nextLine());
String[] a = new String[cases];
int i, c;
//Adding directly to the Set prevents a larger list because you remove the duplicates
Set<String> set = new TreeSet<String>();
for( i = 0; i < cases; i++)
{
a[i] = in.nextLine();
for (c = 0; c < a[i].length(); c++)
{
for (i = 1; i <= a[i].length() - c; i++)
{
String sub = a[i].substring(c, c + i);
set.add(sub);
}
}
}
}
for input :
2
aab
aac
i got a runtime error :
Exception in thread "main" java.lang.NullPointerException
at Solution.main(Solution.java:32)
can anyone explain me why i am getting this runtime error , what should i do to avoid this null pointer exception and why did this occur in the first place? please help me if you can
We have a lot of memory nowadays. But even old days it was considered a bad practice to use the same variable for different purposes. Use each one for one purpose and it will be all right. Code is clear and undersatndable and no more unexplainable exceptions:
import java.io.StringReader;
import java.util.Scanner;
import java.util.Set;
import java.util.TreeSet;
public class Solution {
public static void main(String[] args) {
Scanner in = new Scanner(new StringReader("2\naab\naac\n"));
int cases = Integer.parseInt(in.nextLine());
String[] a = new String[cases];
//int i, c;
// Adding directly to the Set prevents a larger list because you remove
// the duplicates
Set<String> set = new TreeSet<String>();
for (int i = 0; i < cases; i++) {
a[i] = in.nextLine();
for (int c = 0; c < a[i].length(); c++) {
for (int ii = 1; ii <= a[i].length() - c; ii++) {
String sub = a[i].substring(c, c + ii);
set.add(sub);
}
}
}
System.out.println(set);
}
}
P.S. Homework - make name of variables meaningful and unforgetable.
Related
In response to the Hackerank problem: https://www.hackerrank.com/challenges/ctci-making-anagrams/problem where one must find the number, as an integer, of characters to be removed from a string to make it an anagram of another string.
I have completed the code and the program passes the tests but I am wanting help with increasing its efficiency. How do I go about thinking how to improve the efficiency of the following code?
import java.io.*;
import java.math.*;
import java.security.*;
import java.text.*;
import java.util.*;
import java.util.concurrent.*;
import java.util.regex.*;
public class Hackerank {
// Complete the makeAnagram function below.
static int makeAnagram(String a, String b) {
int letterToRemoveCount = 0;
Set<Character> characterMapA = new HashSet<>();
Set<Character> characterMapB = new HashSet<>();
for(int i = 0; i< a.length(); i++) {
if (!characterMapA.contains(a.charAt(i))) {
characterMapA.add(a.charAt(i));
if ((countOccurences(a.charAt(i), a) - countOccurences(a.charAt(i), b)) != 0) {
letterToRemoveCount += Math.abs((countOccurences(a.charAt(i), a) - countOccurences(a.charAt(i), b)));
}
}
}
for (int j = 0; j<b.length(); j++){
if (!characterMapB.contains(b.charAt(j)) && !characterMapA.contains(b.charAt(j))) {
characterMapB.add(b.charAt(j));
if ((countOccurences(b.charAt(j), a) - countOccurences(b.charAt(j), b)) != 0) {
letterToRemoveCount += Math.abs((countOccurences(b.charAt(j), a) - countOccurences(b.charAt(j), b)));
}
}
}
return letterToRemoveCount;
}
public static int countOccurences(char m, String s){
int count = 0;
for(int i = 0; i< s.length(); i++){
if(s.charAt(i) == m){
count++;
}
}
return count;
}
private static final Scanner scanner = new Scanner(System.in);
public static void main(String[] args) throws IOException {
System.out.println(makeAnagram("fcrxzwscanmligyxyvym", "jxwtrhvujlmrpdoqbisbwhmgpmeoke"));
}
}
First rule of optimization: Avoid unnecessary operations:
Like calling to contains before calling add.
Second rule of optimization: If you want it faster, you'd better lean on memory:
Do not call the same function several times with the same input values: Better call only once, store the value in a local variable, and use it afterwards.
Also, computing the number of occurrences of a character in a string is not efficient (the longer the strings, the least efficient): Better create a map for each string, mapping each character to a number of occurrences.
Dave's suggestion about how to optimize such maps is interesting, too.
I really need some assistance so I'm trying so freaking hard to store a str in a list inside a list and this will not freaking work. The code I have written makes perfect sense to me. Can someone please give me some guidance here. I'm desperate. I continously get errors on at line 30 myArrayList.get(index).add(newClassObj);
suggesting >>
at java.util.ArrayList.rangeCheck(ArrayList.java:635)
at java.util.ArrayList.get(ArrayList.java:411)
at myClass.main(myClass.java:30)
public class myCLass {
public static void main(String[] args)
{
ArrayList<LinkedList<myCLass>>
myArrayList = new ArrayList<LinkedList<MyClass>>(26);
inFile file = new inFile();
file.inFile("myfile.txt");
while(inFile.hasNext())
{
String str = inFile.next();
char ch = str.toUpperCase().charAt(0);
char ch2 = 'A';
int index = (int)ch - (int)ch2;
for (int i = 0; i < 26; i++)
myArrayList.add(new LinkedList<MyClass>());
myClass newClassObj = new myClass(str);
myArrayList.get(index).add(newClassObj);
}
}
}
Before you can call myArrayList.get(index).add(newClassObj);, you must make sure that index < myArrayList.size(). Otherwise you'll get an index out of bounds exception.
Your myArrayList's size is 0, since you never add anything to it. Initializing the capacity to 26 doesn't add 26 elements to the list. It doesn't add any elements to the list.
If you wish your list to have 26 elements, you should initialize it properly :
for (int i = 0; i < 26; i++)
myArrayList.add(new LinkedList<MyClass>());
It doesn't look like you're ever making your lists. You have a list that has 26 slots, but you're never filling those slots with a list.
I don't know what this infile is so I just used java.util.Scanner for testing. I also don't see this original MyClass class, so I'm just adding the Strings. Yours is a little different, but the algorithm is the same.
import java.util.*;
import java.io.*;
public class MyClass {
public static void main(String[] args) throws Exception {
ArrayList<LinkedList<String>> list = new ArrayList<>(26);
for(int i = 0; i < 26; i++) {
list.add(new LinkedList<String>());
}
Scanner sc = new Scanner(new File("words.txt"));
while(sc.hasNext()) {
String next = sc.next();
char c = next.toUpperCase().charAt(0);
int index = c - 'A';
list.get(index).add(next);
}
// let's test it by looking at all the H words
System.out.println(list.get(7));
}
}
Result:
C:\files\j>javac MyClass.java
C:\files\j>java MyClass
[have, he, his, her, him, how]
This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 8 years ago.
I am attempting to sort a list of names in alphabetical order and I keep getting the error Exception in thread "main" java.lang.NullPointerException and I don't know why.
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Arrays;
import java.util.Scanner;
public class alphabeticalOrder {
static String names[];
static int count = 0;
static String sorting;
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
String[] names = new String[500];
File namesFile = new File("names.txt");
Scanner inputFile = new Scanner(namesFile);
while (inputFile.hasNextLine()) {
String line = inputFile.nextLine();
String[] namesDetails = line.split(" ");
names[count] = namesDetails[0];
count++;
}
sort();
System.out.println(Arrays.toString(names));
}
public static void sort() {
int namesLength = names.length;
for (int i = 0; i < namesLength - 1; i++) {
for (int j = 0; j < namesLength - 1; j++) {
if (names[j].compareTo(names[j - 1]) > 0) {
sorting = names[j - 1];
names[j - 1] = names[j];
names[j] = sorting;
}
}
}
}
}
Customers txt has these names
Smith, Alexandra
Downes, Trish
Akbal, Maria
and the array must equal 500
Change
if (names[j].compareTo(names[j - 1]) > 0) {
to
if (names[j] != null && names[j].compareTo(names[j - 1]) > 0) {
And the annoying null pointer exception will go away.
If you ever get over your 500 String array obsession I suggest you try TreeSet since it will do all the sorting work for you.
public static void main(String[] args)
{
Set<String> alphabetical = new TreeSet<String>();
alphabetical.add("A");
alphabetical.add("Z");
alphabetical.add("M");
System.out.println(alphabetical);
}
outputs: [A, M, Z]
Your names array has 500 elements, most of which are null. That's why you are getting NullPointerException, when you call names[j].compareTo() for a null reference.
You should only attempt to sort as many names as you get as input.
Instead of
int namesLength = names.length;
Try
int namesLength = count;
Since count holds the number of inputs you actually have.
BTW, your sort() method has other problems :
The loops should go from 0 to namesLength - 1, so the condition should be j < namesLength
names [j-1] would give you ArrayIndexOutOfBoundsException when j==0
You have the array in size 500 and number your names are 6.
when you assign six names to first six indexes of the array, the rest indexes are still having null value. Therefor, comparing with the null value will throw NullPointerException.
why?
Because Objects in Java initialized by null value when they are defined for the first time.
Suggestion :
Try to use ArrayList which shrinks and expands by itself
import java.util.*;
import java.io.*;
import java.io.CharArrayReader;
public class Program2 {
public static void main(String[] args) {
try {
String filename = args[0]; //reads command line argument 1 as filename
Scanner File = new Scanner(new File(filename)); //reads filename into program,and opens it for analysis
File.useDelimiter(System.getProperty("line.seperator"));
ArrayList<String> list = new ArrayList<>(); //creates an array list to store chars to transfer for reading from the file
while (File.hasNext()){
list.add(File.next());
}
File.close();
char[][] array1 = new char[10][20];
for (int i =0; i < list.size(); i++){
array1[i] = list.get(i).toCharArray();
}
} catch (FileNotFoundException e){
System.out.println("File is not found: " + e.getMessage() );//catches and sends out an error message
}
}
static int CharSearch(char[][] array1, char a, char b, char c){
for (int i =0 ; i < array1.length; i++){
for (int j =0; j < array1.length; j++){
while (a == 'A'){
return 1;
Hi all, so I have to make a program that reads in a file that is a 10x20 grid. The grid has letters A, B, C. All chars, in random order. What I need to do, is find a searching algorithm that checks for "groupings" of these letters.
Much like this much smaller version:
AABBACCA
CCABACBA
CCAAAABB
AAAACCCC
So see how there are 3 C groups, 2 B groups, and 3 A groups? (the groups can only be touching horizontally or vertically, not diagonally.)
I have to count that. I tried it, as can be seen on the bottom.
Also, I wanted to also make sure that the rest of my code makes sense and won't just pfft on me.
Thank you :)
I tried sorting strings using bubblesort, but I dont know whether it makes any sense but can someone just help me figure out how to sort strings and let me know if my logic is correct? i have converted the strings to character just to check if they are in alphabetical order..eg app ban acc will be sorted to acc app and ban..can anyone give the logic to this problem.
import java.io.*;
import java.util.*;
class sort
{
public static void main(String args[])throws IOException
{
BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
System.out.println("enter the strings");
String str=br.readLine();
StringTokenizer st=new StringTokenizer(str,",");
String s1=st.nextToken();
String s2=st.nextToken();
String s3=st.nextToken();
char ch1[]=s1.toCharArray();
char ch2[]=s2.toCharArray();
char ch3[]=s3.toCharArray();
if ((ch1[0]<ch2[0])&&(ch1[0]<ch3[0])&&(ch2[0]<ch3[0]))
for(int i=0;i<4;i++)
{
System.out.println(+ch1[i]);
System.out.println(+ch2[i]);
System.out.println(+ch3[i]);
}
else if((ch2[0]<ch1[0]&&ch2[0]<ch3[0]&&ch1[0]<ch3[0]) )
for(int i=0;i<4;i++)
{
System.out.println(+ch2[i]);
System.out.println(+ch1[i]);
System.out.println(+ch3[i]);
}
else if((ch3[0]<ch1[0])&&(ch3[0]<ch2[0])&&ch1[0]<ch2[0])
for(int i=0;i<4;i++)
{
System.out.println(+ch3[i]);
System.out.println(+ch1[i]);
System.out.println(+ch2[i]);
}
}
}
Bubble sort, also known as sinking sort, is a simple sorting algorithm that works by repeatedly stepping through the list to be sorted, comparing each pair of adjacent items and swapping them if they are in the wrong order. The pass through the list is repeated until no swaps are needed, which indicates that the list is sorted. The algorithm gets its name from the way smaller elements "bubble" to the top of the list. Because it only uses comparisons to operate on elements, it is a comparison sort. Although the algorithm is simple, it is not efficient for sorting large lists; other algorithms are better. Wikipedia
The following is the sort-cut way to do so.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
final public class Main
{
public static void main(String[] args) throws IOException
{
BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
System.out.print("Enter the strings:->");
String str=br.readLine();
String strArr[]=str.split(" ");//your sentence will be split into words.
Arrays.sort(strArr);
for(int i=0;i<strArr.length;i++)
{
System.out.println(strArr[i]);
}
}
}
If you wish, you can apply your own logic as follows.
final public class Main
{
public static void main(String[] args) throws IOException
{
BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
System.out.print("Enter the strings:->");
String str=br.readLine();
String strArr[]=str.split(" ");
String temp;
for(int i = 0; i<strArr.length - 1; i++)
{
for(int j = 0; j<strArr.length - 1; j++)
{
if(strArr[j].compareTo(strArr[j+1]) > 0)
{
temp = strArr[j];
strArr[j] = strArr[j+1];
strArr[j+1] = temp;
}
}
}
for(int i=0;i<strArr.length;i++)
{
System.out.println(strArr[i]);
}
}
}
In both the cases, I have assumed spaces as word separator and not commas , that you're using in your example.
First you need to choose how do you want to sort strings ?
is it by length ? is it by alpha order ?
After you choose the appropriated method, you just need to sync it for the existing sorting method of bubblesort.
public static int[] bubble(String[] str_arr) {
for (int i = 0, temp; i < str_arr.length-1; i++) {
for(int j = 0; j < str_arr.length-1; j++) {
if (str_arr[j] < str_arr[j+1]) {
temp = str_arr[j];
str_arr[j] = str_arr[j+1];
str_arr[j+1] = temp;
}
}
}
return str_arr;
}
As i mentions theres couple of ways of comparing strings:
Length - length of a string
Lexicographically - explanation here
If we want to use one of the two method mentioned above, we should change the line:
if (str_arr[j] < str_arr[j+1])
to
if (str_arr[j].length < str_arr[j+1].length)
Or for the lexicographically order we will use:
if (str_arr[j].compareTo(str_arr[j+1].length) < 0)
compareTo is a java String method that checking lexicog.. order.
it returnes:
0 - strings are identical.
positive number - first string is bigger then second string.
negative number - first string is smaller then second string.
String implements interface Comparable (so overrides compareTo() method), thus you can compare two strings (>,<,>=,<=). That's why you don't have to compare every char element by element. Not worth trying even.
The solution: put Strings into array:
String[] stringArray = new String[]{"element1","element2"};
and then use default bubble-sort algorithm:
for (int x = 1; x < stringArray.length; x++) {
for (int y = 0; y < stringArray.length - x; y++) {
if (stringArray[y].compareTo(stringArray[y + 1]) > 0) {
temp = stringArray[y];
stringArray[y] = stringArray[y + 1];
stringArray[y + 1] = temp;
}
}
}
and you should receive sorted array.