Computing Jaccard Similarity in Java - java

I have following the code that loop through array list(mainItems) and find the most similar two arrays and put them in sortedTransactions. It is working fine for small data (10000 transactions) but it is running forever for 88000 transactions. What can be done to make it work for big data.
import java.util.*;
public class Sort {
static private List<Transactions> trans = ReadFile.transactions;
static public List<int[]> mainItems;
static public ArrayList<int[]> sortedTransactions = new ArrayList<int[]>();
static {
mainItems = new ArrayList<int[]>();
for (Transactions t : trans) {
mainItems.add(t.getItems());
}
}
static private double jaccardSimilarity(int[] a, int[] b) {
Set<Integer> s1 = new LinkedHashSet<Integer>();
for(int i =0; i< a.length; i++){
s1.add(a[i]);
}
Set<Integer> s2 = new LinkedHashSet<Integer>();
for(int i =0; i< b.length; i++){
s2.add(b[i]);
}
Set<Integer> intersection = new LinkedHashSet<>(s1);
intersection.retainAll(s2);
Set<Integer> union = new LinkedHashSet<Integer>(s1);
union.addAll(s2);
double jaccardSimilarity = (double)intersection.size()/ (double)union.size();
//System.out.println(intersection);
return jaccardSimilarity;
}
static private boolean isAllEqual(List<Double> a){
for(int i=1; i<a.size(); i++){
if(a.get(0) != a.get(i)){
return false;
}
}
return true;
}
static public void generatePairs() {
for (int i = 0; i < mainItems.size() - 1; i++) {
if (!sortedTransactions.contains(mainItems.get(i))) {
List<Double> myd = new ArrayList<Double>();
List<int[]> mys = new ArrayList<int[]>();
for (int j = i + 1; j < mainItems.size(); j++) {
if (!sortedTransactions.contains(mainItems.get(j))) {
myd.add(jaccardSimilarity(mainItems.get(i),mainItems.get(j)));
mys.add(mainItems.get(j));
}
}
if (isAllEqual(myd) == false) {
sortedTransactions.add(mainItems.get(i));
sortedTransactions.add(mys.get(maxValue(myd)));
}
}
}
}
static private int maxValue(List<Double> d) {
double max = d.get(0);
int f = 0;
for(int i =1; i< d.size(); i++){
if(d.get(i) > max){
max= d.get(i);
f= i;
}
}
return f;
}
}

You don't have to create the union set (union(s1, s2).size() is s1.size() + s2.size() - intersection(s1, s2).size()).
static private double jaccardSimilarity(int[] a, int[] b) {
Set<Integer> s1 = new HashSet<Integer>();
for (int i = 0; i < a.length; i++) {
s1.add(a[i]);
}
Set<Integer> s2 = new HashSet<Integer>();
for (int i = 0; i < b.length; i++) {
s2.add(b[i]);
}
final int sa = s1.size();
final int sb = s2.size();
s1.retainAll(s2);
final int intersection = s1.size();
return 1d / (sa + sb - intersection) * intersection;
}

Related

How to find most common/rare bits in a set of BitSets?

I'm working on a file sync app similar to p2p, where files are mapped by BitSets. And trying to find most rare file pieces among peers to be sent first to the receiver.
package asd;
import java.util.Arrays;
import java.util.BitSet;
import java.util.Random;
public class ChoosePiece
{
static Random rand = new Random();
public static BitSet rand_bit_set(int size)
{
int n_long = (size + 64 -1)/64;
long a[] = new long[n_long];
for (int i = 0; i < a.length; i++) a[i] = rand.nextLong();
// clear unused bits of the last long
int m = size % 64;
a[n_long-1] <<= (64-m);
a[n_long-1] >>>= (64-m);
return BitSet.valueOf(a);
}
public static void main(String args[])
{
int n_sets = 5;
int size = 20;
System.out.println("======== receiver map ==========================");
BitSet reciever_map = rand_bit_set(size);
print(reciever_map, size);
System.out.println("======== peers maps ============================");
BitSet bs[] = new BitSet[n_sets];
for (int i = 0; i < bs.length; i++) bs[i] = rand_bit_set(size);
for (int i = 0; i < bs.length; i++) print(bs[i], size);
IdxCnt cnt[] = new IdxCnt[size];
for (int i = 0; i < cnt.length; i++) cnt[i] = new IdxCnt(i, 0);
for (int i = reciever_map.nextSetBit(0); i >= 0; i = reciever_map.nextSetBit(i+1))
{
for (int j = 0; j < bs.length; j++)
{
if (reciever_map.get(i) && bs[j].get(i)) cnt[i].cnt++;
}
if (i == Integer.MAX_VALUE) break; // or (i+1) would overflow
}
System.out.println("========== count ====================================");
System.out.println(Arrays.toString(cnt));
Arrays.sort(cnt);
System.out.println(Arrays.toString(cnt));
}
public static void print(BitSet bs, int size)
{
System.out.println(bs);
StringBuffer b = new StringBuffer();
for (int i = 0; i < size; i++)
{
char c = bs.get(i) ? '1' : '0';
b.append(c);
}
System.out.println(b.toString());
}
public static class IdxCnt implements Comparable<IdxCnt>
{
public int idx;
public int cnt;
public IdxCnt(int idx, int cnt)
{
this.idx = idx;
this.cnt = cnt;
}
#Override
public String toString()
{
return String.valueOf(cnt);
}
#Override
public int compareTo(IdxCnt o)
{
return -Integer.compare(cnt, o.cnt);
}
}
}
The above code basically counts the bits set, I wander if there is a better way to find most common/rate bits using logical operations over BitSet? Feel like there should be, could be wrong.

USACO Server Input Discrepancy

I'm retrying the USACO Silver Problem Robot Instructions.
On my computer (Macbook Air M1 2020, MacOS Big Sur version 11.3.1), when I manually input the sample case my program outputs the correct answer. However, on the USACO grading server, it displays:
The following appeared on standard error:
Exception in thread "main" java.util.NoSuchElementException
at java.base/java.util.Scanner.throwFor(Scanner.java:937)
at java.base/java.util.Scanner.next(Scanner.java:1594)
at java.base/java.util.Scanner.nextInt(Scanner.java:2258)
at java.base/java.util.Scanner.nextInt(Scanner.java:2212)
at RobotInstructions.main(RobotInstructions.java:33)
For reference, my current code is:
import java.util.ArrayList;
import java.util.Scanner;
import java.lang.Math;
public class RobotInstructions {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int nInstructions = in.nextInt();
int wontx = in.nextInt();
int wonty = in.nextInt();
ArrayList<int[]> a;
ArrayList<int[]> b;
int n1;
int n2;
if (nInstructions%2==0) {
n1 = (int) nInstructions/2;
n2 = (int) nInstructions/2;
} else {
n1 = ((int) (nInstructions-1)/2);
n2 = ((int) (nInstructions+1)/2);
}
/////////////////////////////////
Scanner in1 = new Scanner(System.in);
int[][] instructionList = new int[n1][2];
for (int i = 0; i<n1; i++) {
int a1 = in1.nextInt();
int b1 = in1.nextInt();
instructionList[i][0] = a1;
instructionList[i][1] = b1;
}
a = subset(n1, instructionList);
/////////////////////////////////
/////////////////////////////////
int[][] instructionList1 = new int[n2][2];
for (int i = 0; i<n2; i++) {
int a1 = in1.nextInt();
int b1 = in1.nextInt();
instructionList1[i][0] = a1;
instructionList1[i][1] = b1;
}
b = subset(n2, instructionList1);
/////////////////////////////////
int[] answers = new int[nInstructions];
for (int[] i : a) {
for (int[] j : b) {
if (i[0]+j[0]==wontx && i[1]+j[1]==wonty) {
answers[i[2]+j[2]-1]++;
}
}
}
for (int i : answers) {
System.out.println(i);
}
}
public static ArrayList<int[]> subset(int n, int[][] instructionList) {
ArrayList<int[]> sums = new ArrayList<int[]>();
StringBuilder sb = new StringBuilder();
for (int i = 0; i< (Math.pow(2,n)) ; i++) {
sb.setLength(0);
String a = Integer.toBinaryString(i);
for (int j = 0; j<(n-a.length()); j++) {
sb.append("0");
}
sb.append(a);
String c = sb.toString();
int x = 0;
int y = 0;
int amt = 0;
for (int k = 0; k<n; k++) {
if (c.charAt(k) == '1') {
x += instructionList[k][0];
y += instructionList[k][1];
amt++;
}
}
int[] m = new int[] {x,y,amt};
sums.add(m);
}
return sums;
}
}
I would not like any feedback on the efficiency of my program, just the reason why the grading server doesn't like my input format.

I am facing timeout for my solution for a HackerRank

I am solving a problem on hackerrank
Hacker Rank ICPC Team Problem
I have created the following code as solution for problem.
import java.math.BigInteger;
import java.util.Scanner;
public class ACMICPCTeam {
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner sc=new Scanner(System.in);
int n=sc.nextInt(),m=sc.nextInt(),count=0,maxCount=0,teams=0;
sc.nextLine();
String subjectArray[]=new String[n];
for(int i=0;i<n;i++){
subjectArray[i]=sc.nextLine();
}
for(int i=0;i<n;i++){
for(int j=i+1;j<n;j++){
String temp=""+(new BigInteger(subjectArray[i]).add(new BigInteger(subjectArray[j])));
//System.out.println(temp);
count=temp.replace("0","").length();
if(count>maxCount)
{
maxCount=count;
teams=1;
}
else if(count==maxCount)
{
teams++;
}
}
}
System.out.println(maxCount);
System.out.println(teams);
sc.close();
}
}
So what I am trying to do is I am adding the two teams subjects and I am counting non-zeros of resultant string. The highest count is number of subjects and the occurrence of highest counts are teams which know max number of subject. Even after spending a lot time I am not able to any better solution than this one still I am facing time out as it is not efficient.
I have gone through forum of the question but it was of no help.
Don't use string logic for this.
Parse the string into a BitSet, before entering your loops, i.e. as you read them.
Then use methods or(BitSet set), and cardinality().
I just completed challenge doing that. No timeouts.
Your solution is not optimal you should try something better.
You can utilize BigInteger method or BitSet class to make it easy.
For forming a team you have to use bitwise OR
Here are solutions--
// 1st approach
static int[] acmTeam(String[] topic) {
int n = topic.length;
BigInteger[] bi = new BigInteger[n];
for (int i = 0; i < n; i++)
bi[i] = new BigInteger(topic[i], 2);
int maxTopic = 0;
int teamCount = 0;
for (int i = 0; i < n; i++) {
for (int j = i + 1; j < n; j++) {
BigInteger iuj = bi[i].or(bi[j]);
int bitCount = iuj.bitCount();
if (bitCount > maxTopic) {
maxTopic = bitCount;
teamCount = 1;
} else if (bitCount == maxTopic) {
teamCount++;
}
}
}
int result[] = { maxTopic, teamCount };
return result;
}
// 2nd approach--using java BitSet class
static int[] acmTeamUsingBitSet(String[] topic) {
int teamCount = 0, maxTopic = 0;
int size = topic.length;
BitSet[] bitset = new BitSet[size];
for (int i = 0; i < size; i++) {
BigInteger b1 = new BigInteger(topic[i], 2);
bitset[i] = BitSet.valueOf(b1.toByteArray());
}
for (int i = 0; i < size - 1; i++) {
BitSet bitset1 = bitset[i];
for (int j = i + 1; j < size; j++) {
BitSet bitset2 = bitset[j];
BitSet tmpset = new BitSet();
tmpset.or(bitset1);
tmpset.or(bitset2);
if (tmpset.cardinality() > maxTopic) {
maxTopic = tmpset.cardinality();
teamCount = 1;
} else if (maxTopic == tmpset.cardinality()) {
teamCount++;
}
}
}
int result[] = { maxTopic, teamCount };
return result;
}
You can refer this link for a detailed video explanation.
I got good result using Java 8.
static int[] acmTeam(String[] topic) {
List<List<Integer>> res = IntStream.range(0, topic.length)
.mapToObj(s -> IntStream.range(0, topic[s].length()).boxed()
.collect(Collectors.groupingBy(i -> topic[s].charAt(i))))
.map(m -> m.get('1'))
.collect(toList());
long maxTopic = 0;
int teamCount = 0;
for (int i = 0; i < res.size(); i++) {
for (int j = i + 1; j < res.size(); j++) {
long topics = Stream.concat(res.get(i).stream(), res.get(j).stream()).distinct().count();
if (topics > maxTopic) {
maxTopic = topics;
teamCount = 1;
} else if (topics == maxTopic) {
teamCount++;
}
}
}
return new int[]{(int) maxTopic, teamCount};
}

Program with threads for matrix multiplication

I'm trying to create a Java program with threads for matrix multiplication. This is the source code:
import java.util.Random;
public class MatrixTest {
//Creating the matrix
static int[][] mat = new int[3][3];
static int[][] mat2 = new int[3][3];
static int[][] result = new int[3][3];
public static void main(String[] args) {
//Creating the object of random class
Random rand = new Random();
//Filling first matrix with random values
for (int i = 0; i < mat.length; i++) {
for (int j = 0; j < mat[i].length; j++) {
mat[i][j] = rand.nextInt(10);
}
}
//Filling second matrix with random values
for (int i = 0; i < mat2.length; i++) {
for (int j = 0; j < mat2[i].length; j++) {
mat2[i][j] = rand.nextInt(10);
}
}
try {
//Object of multiply Class
Multiply multiply = new Multiply(3, 3);
//Threads
MatrixMultiplier thread1 = new MatrixMultiplier(multiply);
MatrixMultiplier thread2 = new MatrixMultiplier(multiply);
MatrixMultiplier thread3 = new MatrixMultiplier(multiply);
//Implementing threads
Thread th1 = new Thread(thread1);
Thread th2 = new Thread(thread2);
Thread th3 = new Thread(thread3);
//Starting threads
th1.start();
th2.start();
th3.start();
th1.join();
th2.join();
th3.join();
} catch (Exception e) {
e.printStackTrace();
}
//Printing the result
System.out.println("\n\nResult:");
for (int i = 0; i < result.length; i++) {
for (int j = 0; j < result[i].length; j++) {
System.out.print(result[i][j] + " ");
}
System.out.println();
}
}//End main
}//End Class
//Multiply Class
class Multiply extends MatrixTest {
private int i;
private int j;
private int chance;
public Multiply(int i, int j) {
this.i = i;
this.j = j;
chance = 0;
}
//Matrix Multiplication Function
public synchronized void multiplyMatrix() {
int sum = 0;
int a = 0;
for (a = 0; a < i; a++) {
sum = 0;
for (int b = 0; b < j; b++) {
sum = sum + mat[chance][b] * mat2[b][a];
}
result[chance][a] = sum;
}
if (chance >= i)
return;
chance++;
}
}//End multiply class
//Thread Class
class MatrixMultiplier implements Runnable {
private final Multiply mul;
public MatrixMultiplier(Multiply mul) {
this.mul = mul;
}
#Override
public void run() {
mul.multiplyMatrix();
}
}
I just tried on Eclipse and it works, but now I want to create another version of that program in which, I use one thread for each cell that I'll have on the result matrix. For example I've got two 3x3 matrices. So the result matrix will be 3x3. Then, I want to use 9 threads to calculate each one of the 9 cells of the result matrix.
Can anyone help me?
You can create n Threads as follows (Note: numberOfThreads is the number of threads that you want to create. This will be the number of cells):
List<Thread> threads = new ArrayList<>(numberOfThreads);
for (int x = 0; x < numberOfThreads; x++) {
Thread t = new Thread(new MatrixMultiplier(multiply));
t.start();
threads.add(t);
}
for (Thread t : threads) {
t.join();
}
Please use the new Executor framework to create Threads, instead of manually doing the plumbing.
ExecutorService executor = Executors.newFixedThreadPool(numberOfThreadsInPool);
for (int i = 0; i < numberOfThreads; i++) {
Runnable worker = new Thread(new MatrixMultiplier(multiply));;
executor.execute(worker);
}
executor.shutdown();
while (!executor.isTerminated()) {
}
With this code i think that i resolve my problem. I don't use synchronized in the methods but i think that is not necessary in that case.
import java.util.Scanner;
class MatrixProduct extends Thread {
private int[][] A;
private int[][] B;
private int[][] C;
private int rig, col;
private int dim;
public MatrixProduct(int[][] A, int[][] B, int[][] C, int rig, int col, int dim_com) {
this.A = A;
this.B = B;
this.C = C;
this.rig = rig;
this.col = col;
this.dim = dim_com;
}
public void run() {
for (int i = 0; i < dim; i++) {
C[rig][col] += A[rig][i] * B[i][col];
}
System.out.println("Thread " + rig + "," + col + " complete.");
}
}
public class MatrixMultiplication {
public static void main(String[] args) {
Scanner In = new Scanner(System.in);
System.out.print("Row of Matrix A: ");
int rA = In.nextInt();
System.out.print("Column of Matrix A: ");
int cA = In.nextInt();
System.out.print("Row of Matrix B: ");
int rB = In.nextInt();
System.out.print("Column of Matrix B: ");
int cB = In.nextInt();
System.out.println();
if (cA != rB) {
System.out.println("We can't do the matrix product!");
System.exit(-1);
}
System.out.println("The matrix result from product will be " + rA + " x " + cB);
System.out.println();
int[][] A = new int[rA][cA];
int[][] B = new int[rB][cB];
int[][] C = new int[rA][cB];
MatrixProduct[][] thrd = new MatrixProduct[rA][cB];
System.out.println("Insert A:");
System.out.println();
for (int i = 0; i < rA; i++) {
for (int j = 0; j < cA; j++) {
System.out.print(i + "," + j + " = ");
A[i][j] = In.nextInt();
}
}
System.out.println();
System.out.println("Insert B:");
System.out.println();
for (int i = 0; i < rB; i++) {
for (int j = 0; j < cB; j++) {
System.out.print(i + "," + j + " = ");
B[i][j] = In.nextInt();
}
}
System.out.println();
for (int i = 0; i < rA; i++) {
for (int j = 0; j < cB; j++) {
thrd[i][j] = new MatrixProduct(A, B, C, i, j, cA);
thrd[i][j].start();
}
}
for (int i = 0; i < rA; i++) {
for (int j = 0; j < cB; j++) {
try {
thrd[i][j].join();
} catch (InterruptedException e) {
}
}
}
System.out.println();
System.out.println("Result");
System.out.println();
for (int i = 0; i < rA; i++) {
for (int j = 0; j < cB; j++) {
System.out.print(C[i][j] + " ");
}
System.out.println();
}
}
}
Consider Matrix.java and Main.java as follows.
public class Matrix extends Thread {
private static int[][] a;
private static int[][] b;
private static int[][] c;
/* You might need other variables as well */
private int i;
private int j;
private int z1;
private int s;
private int k;
public Matrix(int[][] A, final int[][] B, final int[][] C, int i, int j, int z1) { // need to change this, might
// need some information
a = A;
b = B;
c = C;
this.i = i;
this.j = j;
this.z1 = z1; // a[0].length
}
public void run() {
synchronized (c) {
// 3. How to allocate work for each thread (recall it is the run function which
// all the threads execute)
// Here this code implements the allocated work for perticular thread
// Each element of the resulting matrix will generate by a perticular thread
for (s = 0, k = 0; k < z1; k++)
s += a[i][k] * b[k][j];
c[i][j] = s;
}
}
public static int[][] returnC() {
return c;
}
public static int[][] multiply(final int[][] a, final int[][] b) {
/*
* check if multipication can be done, if not return null allocate required
* memory return a * b
*/
final int x = a.length;
final int y = b[0].length;
final int z1 = a[0].length;
final int z2 = b.length;
if (z1 != z2) {
System.out.println("Cannnot multiply");
return null;
}
final int[][] c = new int[x][y];
int i, j;
// 1. How to use threads to parallelize the operation?
// Every element in the resulting matrix will be determined by a different
// thread
// 2. How may threads to use?
// x * y threads are used to generate the result.
for (i = 0; i < x; i++)
for (j = 0; j < y; j++) {
try {
Matrix temp_thread = new Matrix(a, b, c, i, j, z1);
temp_thread.start();
// 4. How to synchronize?
// synchronized() is used with join() to guarantee that the perticular thread
// will be accessed first
temp_thread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
return Matrix.returnC();
}
}
You can use Main.java to give 2 matrices that need to be multiplied.
class Main {
public static int[][] a = {
{1, 1, 1},
{1, 1, 1},
{1, 1, 1}};
public static int[][] b = {
{1},
{1},
{1}};
public static void print_matrix(int[][] a) {
for (int i = 0; i < a.length; i++) {
for (int j = 0; j < a[i].length; j++)
System.out.print(a[i][j] + " ");
System.out.println();
}
}
public static void main(String[] args) {
int[][] x = Matrix.multiply(a, b);
print_matrix(x); // see if the multipication is correct
}
}
In simple terms, what you all need to do is,
1) Create n (no of cells in resultant matrix) threads. Assign their roles. (Ex: Consider M X N, where M and N are matrices. 'thread1' is responsible for the multiplication of M's row_1 elements with N's column_1 elements and storing the result. This is the value for the resultant matrix's cell_1.)
2) Start each thread's process. (by start() method)
3) Wait until all the threads finish their processes and store the resultant value of each cell. Because those processes should be finished before displaying the resultant matrix. (You can do this by join() methods, and other possibilities too)
4) Now, you can display the resultant matrix.
Note:
1) Since, in this example, the shared resources (M and N) are only used to read only purpose, you don't need to use 'synchronized' methods to access them.
2) You can see, in this program, there are a group of threads running and all of them needs to achieve a specific status by their own, before continuing the next step of the whole program. This multi-threaded programming model is known as a Barrier.
Tried below code in eclipse as per thread for each cell. It works fine, you can check it.
class ResMatrix {
static int[][] arrres = new int[2][2];
}
class Matrix {
int[][] arr = new int[2][2];
void setV(int v) {
//int tmp = v;
for (int i = 0; i < 2; i++) {
for (int j = 0; j < 2; j++) {
arr[i][j] = v;
v = v + 1;
}
}
}
int[][] getV() {
return arr;
}
}
class Mul extends Thread {
public int row;
public int col;
Matrix m;
Matrix m1;
Mul(int row, int col, Matrix m, Matrix m1) {
this.row = row;
this.col = col;
this.m = m;
this.m1 = m1;
}
public void run() {
//System.out.println("Started Thread: " + Thread.currentThread().getName());
int tmp = 0;
for (int i = 0; i < 2; i++) {
tmp = tmp + this.m.getV()[row][i] * this.m1.getV()[i][col];
}
ResMatrix.arrres[row][col] = tmp;
System.out.println("Started Thread END: " + Thread.currentThread().getName());
}
}
public class Test {
//static int[][] arrres =new int[2][2];
public static void main(String[] args) throws InterruptedException {
Matrix mm = new Matrix();
mm.setV(1);
Matrix mm1 = new Matrix();
mm1.setV(2);
for (int i = 0; i < 2; i++) {
for (int j = 0; j < 2; j++) {
Mul mul = new Mul(i, j, mm, mm1);
mul.start();
// mul.join();
}
}
for (int i = 0; i < 2; i++) {
for (int j = 0; j < 2; j++) {
System.out.println("VALUE: " + ResMatrix.arrres[i][j]);
}
}
}
}
In my solution I assigned to each worker a number of rows numRowForThread equals to: (number of rows of matA) / (number of threads).
public class MatMulConcur {
private final static int NUM_OF_THREAD = 1;
private static Mat matC;
public static Mat matmul(Mat matA, Mat matB) {
matC = new Mat(matA.getNRows(), matB.getNColumns());
return mul(matA, matB);
}
private static Mat mul(Mat matA, Mat matB) {
int numRowForThread;
int numRowA = matA.getNRows();
int startRow = 0;
Worker[] myWorker = new Worker[NUM_OF_THREAD];
for (int j = 0; j < NUM_OF_THREAD; j++) {
if (j < NUM_OF_THREAD - 1) {
numRowForThread = (numRowA / NUM_OF_THREAD);
} else {
numRowForThread = (numRowA / NUM_OF_THREAD) + (numRowA % NUM_OF_THREAD);
}
myWorker[j] = new Worker(startRow, startRow + numRowForThread, matA, matB);
myWorker[j].start();
startRow += numRowForThread;
}
for (Worker worker : myWorker) {
try {
worker.join();
} catch (InterruptedException e) {
}
}
return matC;
}
private static class Worker extends Thread {
private int startRow, stopRow;
private Mat matA, matB;
public Worker(int startRow, int stopRow, Mat matA, Mat matB) {
super();
this.startRow = startRow;
this.stopRow = stopRow;
this.matA = matA;
this.matB = matB;
}
#Override
public void run() {
for (int i = startRow; i < stopRow; i++) {
for (int j = 0; j < matB.getNColumns(); j++) {
double sum = 0;
for (int k = 0; k < matA.getNColumns(); k++) {
sum += matA.get(i, k) * matB.get(k, j);
}
matC.set(i, j, sum);
}
}
}
}
}
where for the class Mat, I used this implementation:
public class Mat {
private double[][] mat;
public Mat(int n, int m) {
mat = new double[n][m];
}
public void set(int i, int j, double v) {
mat[i][j] = v;
}
public double get(int i, int j) {
return mat[i][j];
}
public int getNRows() {
return mat.length;
}
public int getNColumns() {
return mat[0].length;
}
}

appendCodePoint() and codePointAt()

Why does the following program print false, and what changes would I have to make to make it print true?
public class Main {
static int[] codePoints(String s) {
int n = s.length();
int[] temp = new int[n];
for (int i = 0; i < n; i++)
temp[i] = s.codePointAt(i);
return temp;
}
static String construct(int[] codePoints) {
StringBuilder sb = new StringBuilder();
for (int i : codePoints)
sb.appendCodePoint(i);
return sb.toString();
}
public static void main(String[] args) {
StringBuilder sb = new StringBuilder("The symbol ");
sb.appendCodePoint(Character.MAX_VALUE + 1);
sb.append(" is not in the Basic Multilingual Plane.");
String s = sb.toString();
System.out.println(s.equals(construct(codePoints(s))));
}
}
The problem is here:
static int[] codePoints(String s) {
int n = s.length();
int[] temp = new int[n];
for (int i = 0; i < n; i++)
temp[i] = s.codePointAt(i); // <-- HERE
return temp;
}
A code point outside the BMP is two chars wide, not one (see Character.toChars()); you need to check that and advance your index if you encounter such a code point:
static int[] codePoints(final String s)
{
final int len = s.length();
final int[] ret = new int[s.codePointCount(0, len)];
int nrCodePoints = 0;
int codePoint;
int index;
for (index = 0; index < len; index++) {
codePoint = s.codePointAt(index);
ret[nrCodePoints++] = codePoint;
if (codePoint > Character.MAX_VALUE)
index++;
}
return ret;
}

Categories

Resources