I use nearly the same method as in the discussion. But mine reaches the time limitation but his passes all cases. I want to know how to improve my code and why there is difference?
Here is my entire code:
boolean[] visited;
public int dfs(int step, int[] edges, int node, Map<Integer, Integer> path) {
path.put(node, step);
visited[node] = true;
if (edges[node] == -1) {
return -1;
}
if (path.containsKey(edges[node])) {
return step - path.get(edges[node]) + 1;
}
return dfs(step + 1, edges, edges[node], path);
}
public int longestCycle(int[] edges) {
int res = -1;
visited = new boolean[edges.length];
for (int i = 0; i < edges.length; i++) {
if (visited[i]) {
continue;
}
int maxCircleLength = dfs(0, edges, i, new HashMap<Integer, Integer>());
res = Math.max(maxCircleLength, res);
}
return res;
}
This is his solution:
public int longestCycle(int[] edges) {
int longest = -1;
boolean visited[] = new boolean[edges.length]; // global visisted
HashMap<Integer, Integer> map;
for(int i=0; i<edges.length; i++){
if(visited[i]) continue;
int distance = 0, curr_node = i;
map = new HashMap<>(); // local visited
while(curr_node != -1){
if(map.containsKey(curr_node)){
longest = Math.max(longest, distance - map.get(curr_node));
break;
}
if(visited[curr_node]) break;
visited[curr_node] = true;
map.put(curr_node, distance);
curr_node = edges[curr_node];
distance++;
}
}
return longest;
}
Given: LDAP stores location of users.
How do I drive their timezones using their location? Any pointers are accepted, Java language preferred.
Thanks in advance.
This depends on information the "location" contains? You'd somehow need to map the location to a timezone name, preferably the Olson style timezone names, because they are more detailed and easier to map, as they are locations themselves.
If it's an approximate addres (like country and city or so) then several geolocation services do include timezones in their information, so you can call these services and see.
If it's a geolocation with latitude and longitude then a site called Earthtools can give you the timezone. http://www.earthtools.org/webservices.htm#timezone
There is this database that provides mappings from cities and countries to timezones: http://citytimezones.info/cms/pending_requests.htm
Unfortunately it uses Windows timezone names, but you can this data http://unicode.org/repos/cldr/trunk/common/supplemental/windowsZones.xml from Unicode.org to map between Windows timezone names and the Olson TZ names.
I haven't actually done this but the following should work:
You can first use GeoGoogle java library to get the longitude/latitude from the city-state-country.
Next, you can use EarthTools (and some java code of your own) mentioned by Lennart to get the timezone :)
We are using the MaxMind GeoIP database to get information regarding the location of a user. They have a paid version (99.8% accuracy) as well as a free version (99.5% accuracy).
They also provide you with APIs in Java, C, PHP etc that will enable you to query its database which you can download and keep locally (updates provided each month). The database provides you info regarding the client city, state, country etc on the basis of IP addresses.
Hope this helps.
Try this code for use Google Time Zone API from Java:
String get_xml_server_reponse(String server_url){
URL xml_server = null;
String xmltext = "";
InputStream input;
try {
xml_server = new URL(server_url);
try {
input = xml_server.openConnection().getInputStream();
final BufferedReader reader = new BufferedReader(new InputStreamReader(input));
final StringBuilder sBuf = new StringBuilder();
String line = null;
try {
while ((line = reader.readLine()) != null)
{
sBuf.append(line);
}
}
catch (IOException e)
{
Log.e(e.getMessage(), "XML parser, stream2string 1");
}
finally {
try {
input.close();
}
catch (IOException e)
{
Log.e(e.getMessage(), "XML parser, stream2string 2");
}
}
xmltext = sBuf.toString();
} catch (IOException e1) {
e1.printStackTrace();
}
} catch (MalformedURLException e1) {
e1.printStackTrace();
}
return xmltext;
}
private String get_UTC_Datetime_from_timestamp(long timeStamp){
try{
Calendar cal = Calendar.getInstance();
TimeZone tz = cal.getTimeZone();
int tzt = tz.getOffset(System.currentTimeMillis());
timeStamp -= tzt;
// DateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss",Locale.getDefault());
DateFormat sdf = new SimpleDateFormat();
Date netDate = (new Date(timeStamp));
return sdf.format(netDate);
}
catch(Exception ex){
return "";
}
}
class NTP_UTC_Time
{
private static final String TAG = "SntpClient";
private static final int RECEIVE_TIME_OFFSET = 32;
private static final int TRANSMIT_TIME_OFFSET = 40;
private static final int NTP_PACKET_SIZE = 48;
private static final int NTP_PORT = 123;
private static final int NTP_MODE_CLIENT = 3;
private static final int NTP_VERSION = 3;
// Number of seconds between Jan 1, 1900 and Jan 1, 1970
// 70 years plus 17 leap days
private static final long OFFSET_1900_TO_1970 = ((365L * 70L) + 17L) * 24L * 60L * 60L;
private long mNtpTime;
public boolean requestTime(String host, int timeout) {
try {
DatagramSocket socket = new DatagramSocket();
socket.setSoTimeout(timeout);
InetAddress address = InetAddress.getByName(host);
byte[] buffer = new byte[NTP_PACKET_SIZE];
DatagramPacket request = new DatagramPacket(buffer, buffer.length, address, NTP_PORT);
buffer[0] = NTP_MODE_CLIENT | (NTP_VERSION << 3);
writeTimeStamp(buffer, TRANSMIT_TIME_OFFSET);
socket.send(request);
// read the response
DatagramPacket response = new DatagramPacket(buffer, buffer.length);
socket.receive(response);
socket.close();
mNtpTime = readTimeStamp(buffer, RECEIVE_TIME_OFFSET);
} catch (Exception e) {
// if (Config.LOGD) Log.d(TAG, "request time failed: " + e);
return false;
}
return true;
}
public long getNtpTime() {
return mNtpTime;
}
/**
* Reads an unsigned 32 bit big endian number from the given offset in the buffer.
*/
private long read32(byte[] buffer, int offset) {
byte b0 = buffer[offset];
byte b1 = buffer[offset+1];
byte b2 = buffer[offset+2];
byte b3 = buffer[offset+3];
// convert signed bytes to unsigned values
int i0 = ((b0 & 0x80) == 0x80 ? (b0 & 0x7F) + 0x80 : b0);
int i1 = ((b1 & 0x80) == 0x80 ? (b1 & 0x7F) + 0x80 : b1);
int i2 = ((b2 & 0x80) == 0x80 ? (b2 & 0x7F) + 0x80 : b2);
int i3 = ((b3 & 0x80) == 0x80 ? (b3 & 0x7F) + 0x80 : b3);
return ((long)i0 << 24) + ((long)i1 << 16) + ((long)i2 << 8) + (long)i3;
}
/**
* Reads the NTP time stamp at the given offset in the buffer and returns
* it as a system time (milliseconds since January 1, 1970).
*/
private long readTimeStamp(byte[] buffer, int offset) {
long seconds = read32(buffer, offset);
long fraction = read32(buffer, offset + 4);
return ((seconds - OFFSET_1900_TO_1970) * 1000) + ((fraction * 1000L) / 0x100000000L);
}
/**
* Writes 0 as NTP starttime stamp in the buffer. --> Then NTP returns Time OFFSET since 1900
*/
private void writeTimeStamp(byte[] buffer, int offset) {
int ofs = offset++;
for (int i=ofs;i<(ofs+8);i++)
buffer[i] = (byte)(0);
}
}
String get_time_zone_time(GeoPoint gp){
String erg = "";
String raw_offset = "";
String dst_offset = "";
double Longitude = gp.getLongitudeE6()/1E6;
double Latitude = gp.getLatitudeE6()/1E6;
// String request = "http://ws.geonames.org/timezone?lat="+Latitude+"&lng="+ Longitude+ "&style=full";
long tsLong = 0; // System.currentTimeMillis()/1000;
NTP_UTC_Time client = new NTP_UTC_Time();
if (client.requestTime("pool.ntp.org", 2000)) {
tsLong = client.getNtpTime();
}
if (tsLong != 0)
{
tsLong = tsLong / 1000;
// https://maps.googleapis.com/maps/api/timezone/xml?location=39.6034810,-119.6822510×tamp=1331161200&sensor=true
String request = "https://maps.googleapis.com/maps/api/timezone/xml?location="+Latitude+","+ Longitude+ "×tamp="+tsLong +"&sensor=true";
String xmltext = get_xml_server_reponse(request);
if(xmltext.compareTo("")!= 0)
{
int startpos = xmltext.indexOf("<TimeZoneResponse");
xmltext = xmltext.substring(startpos);
XmlPullParser parser;
try {
parser = XmlPullParserFactory.newInstance().newPullParser();
parser.setInput(new StringReader (xmltext));
int eventType = parser.getEventType();
String tagName = "";
while(eventType != XmlPullParser.END_DOCUMENT) {
switch(eventType) {
case XmlPullParser.START_TAG:
tagName = parser.getName();
break;
case XmlPullParser.TEXT :
if (tagName.equalsIgnoreCase("raw_offset"))
if(raw_offset.compareTo("")== 0)
raw_offset = parser.getText();
if (tagName.equalsIgnoreCase("dst_offset"))
if(dst_offset.compareTo("")== 0)
dst_offset = parser.getText();
break;
}
try {
eventType = parser.next();
} catch (IOException e) {
e.printStackTrace();
}
}
} catch (XmlPullParserException e) {
e.printStackTrace();
erg += e.toString();
}
}
int ro = 0;
if(raw_offset.compareTo("")!= 0)
{
float rof = str_to_float(raw_offset);
ro = (int)rof;
}
int dof = 0;
if(dst_offset.compareTo("")!= 0)
{
float doff = str_to_float(dst_offset);
dof = (int)doff;
}
tsLong = (tsLong + ro + dof) * 1000;
erg = get_UTC_Datetime_from_timestamp(tsLong);
}
return erg;
}
And use it with:
GeoPoint gp = new GeoPoint(39.6034810,-119.6822510);
String Current_TimeZone_Time = get_time_zone_time(gp);
I want to partition a QByteArray message efficiently, so this function I implemented take the Bytes, the part I want to extract, and toEnd flag which tells if I want to extract part1 till the end of the array. my dilimeter is spcae ' '
example if I have:
ba = "HELLO HOW ARE YOU?"
ba1 = getPart(ba, 1, false) -> ba1 = "HELLO"
ba2 = getPart(ba, 2, true) -> ba2 = "HOW ARE YOU?"
ba3 = getPart(ba, 3, false) -> ba3 = "ARE"
the function below works just fine, but I am wondering if this is efficient. should I consider using split function?
QByteArray Server::getPart(const QByteArray message, int part, bool toEnd)
{
QByteArray string;
int startsFrom = 0;
int endsAt = 0;
int count = 0;
for(int i = 0; i < message.size(); i++)
{
if(message.at(i) == ' ')
{
count++;
if(part == count)
{
endsAt = i;
break;
}
string.clear();
startsFrom = i + 1;
}
string.append(message.at(i));
}
if(toEnd)
{
for(int i = endsAt; i < message.size(); i++)
{
string.append(message.at(i));
}
}
return string;
}
What about this:
QByteArray Server::getPart(const QByteArray& message, int part, bool toEnd)
{
int characters(toEnd ? -1 : message.indexOf(' ', part) - part);
return message.mid(part, characters);
}
Why not make it a regular QString and use split. That will give you a QStringList.
Hi im trying to figure out how to recursively search a tree to find a character and the binary code to get to that character. basically the goal is to go find the code for the character and then write it to a file. the file writer part i can do no problem but the real problem is putting the binary code into a string. while im searching for the character. please help!
this is the code for the recursive method:
public String biNum(Frequency root, String temp, String letter)
{
//String temp = "";
boolean wentLeft = false;
if(root.getString() == null && !wentLeft)
{
if(root.left.getString() == null)
{
temp = temp + "0";
return biNum(root.left, temp, letter);
}
if(root.left.getString().equals(letter))
{
return temp = temp + "0";
}
else
{
wentLeft = true;
temp = temp.substring(0, temp.length() - 1);
return temp;
}
}
if(root.getString() == null && wentLeft)
{
if(root.right.getString() == null)
{
temp = temp + "1";
return (biNum(root.right, temp, letter));
}
if(root.right.getString().equals(letter))
{
return temp = temp + "1";
}
else
{
wentLeft = false;
temp = temp.substring(0, temp.length() - 1);
return temp;
}
}
return temp;
}
and this is the Frequency class:
package huffman;
public class Frequency implements Comparable {
private String s;
private int n;
public Frequency left;
public Frequency right;
private String biNum;
private String leaf;
Frequency(String s, int n, String biNum)
{
this.s = s;
this.n = n;
this.biNum = biNum;
}
public String getString()
{
return s;
}
public int getFreq()
{
return n;
}
public void setFreq(int n)
{
this.n = n;
}
public String getLeaf()
{
return leaf;
}
public void setLeaf()
{
this.leaf = "leaf";
}
#Override
public int compareTo(Object arg0) {
Frequency other = (Frequency)arg0;
return n < other.n ? -1 : (n == other.n ? 0 : 1);
}
}
In your updated version, I think you should re-examine return biNum(root.left, temp, letter);. Specifically, what happens if the root node of the entire tree has a left child which is not a leaf (and thus root.left.getString() == null) but the value you seek descends from the right child of the root node of the entire tree.
Consider this tree, for example:
26
/ \
/ \
/ \
11 15
/ \ / \
/ B A \
6 5 6 9
/ \ / \
D \ C sp
3 3 4 5
/ \
E F
2 1
and trace the steps your function will follow looking for the letter C.
Perhaps you should consider traversing the entire tree (and building up the pattern of 1s and 0s as you go) without looking for any specific letter but taking a particular action when you find a leaf node?
Implement Biginteger Multiply
use integer array to store a biginteger
like 297897654 will be stored as {2,9,7,8,9,7,6,5,4}
implement the multiply function for bigintegers
Expamples: {2, 9, 8, 8, 9, 8} * {3,6,3,4,5,8,9,1,2} = {1,0,8,6,3,7,1,4,1,8,7,8,9,7,6}
I failed to implement this class and thought it for a few weeks, couldn't get the answer.
Anybody can help me implement it using C#/Java?
Thanks a lot.
Do you know how to do multiplication on paper?
123
x 456
-----
738
615
492
-----
56088
I would just implement that algorithm in code.
C++ Implementation:
Source Code:
#include <iostream>
using namespace std;
int main()
{
int a[10] = {8,9,8,8,9,2};
int b[10] = {2,1,9,8,5,4,3,6,3};
// INPUT DISPLAY
for(int i=9;i>=0;i--) cout << a[i];
cout << " x ";
for(int i=9;i>=0;i--) cout << b[i];
cout << " = ";
int c[20] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
for(int i=0;i<10;i++)
{
int carry = 0;
for(int j=0;j<10;j++)
{
int t = (a[j] * b[i]) + c[i+j] + carry;
carry = t/10;
c[i+j] = t%10;
}
}
// RESULT DISPLAY
for(int i=19;i>=0;i--) cout << c[i];
cout << endl;
}
Output:
0000298898 x 0363458912 = 00000108637141878976
There is a superb algorithm called Karatsuba algorithm..Here
Which uses divide and conquer startegy..Where you can multiply large numbers..
I have implemented my it in java..
Using some manipulation..
package aoa;
import java.io.*;
public class LargeMult {
/**
* #param args the command line arguments
*/
public static void main(String[] args) throws IOException
{
// TODO code application logic here
BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
System.out.println("Enter 1st number");
String a=br.readLine();
System.out.println("Enter 2nd number");
String b=br.readLine();
System.out.println("Result:"+multiply(a,b));
}
static String multiply(String t1,String t2)
{
if(t1.length()>1&&t2.length()>1)
{
int mid1=t1.length()/2;
int mid2=t2.length()/2;
String a=t1.substring(0, mid1);//Al
String b=t1.substring(mid1, t1.length());//Ar
String c=t2.substring(0, mid2);//Bl
String d=t2.substring(mid2, t2.length());//Br
String s1=multiply(a, c);
String s2=multiply(a, d);
String s3=multiply(b, c);
String s4=multiply(b, d);
long ans;
ans=Long.parseLong(s1)*(long)Math.pow(10,
b.length()+d.length())+Long.parseLong(s3)*(long)Math.pow(10,d.length())+
Long.parseLong(s2)*(long)Math.pow(10, b.length())+Long.parseLong(s4);
return ans+"";
}
else
{
return (Integer.parseInt(t1)*Integer.parseInt(t2))+"";
}
}
}
I hope this helps!!Enjoy..
Give the number you want to multiply in integer type array i.e. int[] one & int[] two.
public class VeryLongMultiplication {
public static void main(String args[]){
int[] one={9,9,9,9,9,9};
String[] temp=new String[100];
int c=0;
String[] temp1=new String[100];
int c1=0;
int[] two={9,9,9,9,9,9};
int car=0,mul=1; int rem=0; int sum=0;
String str="";
////////////////////////////////////////////
for(int i=one.length-1;i>=0;i--)
{
for(int j=two.length-1;j>=0;j--)
{
mul=one[i]*two[j]+car;
rem=mul%10;
car=mul/10;
if(j>0)
str=rem+str;
else
str=mul+str;
}
temp[c]=str;
c++;
str="";
car=0;
}
////////////////////////////////////////
for(int jk=0;jk<c;jk++)
{
for(int l=c-jk;l>0;l--)
str="0"+str;
str=str+temp[jk];
for(int l=0;l<=jk-1;l++)
str=str+"0";
System.out.println(str);
temp1[c1]=str;
c1++;
str="";
}
///////////////////////////////////
String ag="";int carry=0;
System.out.println("========================================================");
for(int jw=temp1[0].length()-1;jw>=0;jw--)
{
for(int iw=0;iw<c1;iw++)
{
int x=temp1[iw].charAt(jw)-'0';
sum+=x;
}
sum+=carry;
int n=sum;
sum=n%10;carry=n/10;
ag=sum+ag;
sum=0;
}
System.out.println(ag);
}
}
Output:
0000008999991
0000089999910
0000899999100
0008999991000
0089999910000
0899999100000
______________
0999998000001
If you do it the long-hand way, you'll have to implement an Add() method too to add up all the parts at the end. I started there just to get the ball rolling. Once you have the Add() down, the Multipy() method gets implemented along the same lines.
public static int[] Add(int[] a, int[] b) {
var maxLen = (a.Length > b.Length ? a.Length : b.Length);
var carryOver = 0;
var result = new List<int>();
for (int i = 0; i < maxLen; i++) {
var idx1 = a.Length - i - 1;
var idx2 = b.Length - i - 1;
var val1 = (idx1 < 0 ? 0 : a[idx1]);
var val2 = (idx2 < 0 ? 0 : b[idx2]);
var addResult = (val1 + val2) + carryOver;
var strAddResult = String.Format("{0:00}", addResult);
carryOver = Convert.ToInt32(strAddResult.Substring(0, 1));
var partialAddResult = Convert.ToInt32(strAddResult.Substring(1));
result.Insert(0, partialAddResult);
}
if (carryOver > 0) result.Insert(0, carryOver);
return result.ToArray();
}
Hint: use divide-and-conquer to split the int into halves, this can effectively reduce the time complexity from O(n^2) to O(n^(log3)). The gist is the reduction of multiplication operations.
I'm posting java code that I wrote. Hope, this will help
import org.junit.Test;
import static org.junit.Assert.*;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
* Created by ${YogenRai} on 11/27/2015.
*
* method multiply BigInteger stored as digits in integer array and returns results
*/
public class BigIntegerMultiply {
public static List<Integer> multiply(int[] num1,int[] num2){
BigInteger first=new BigInteger(toString(num1));
BigInteger result=new BigInteger("0");
for (int i = num2.length-1,k=1; i >=0; i--,k=k*10) {
result = (first.multiply(BigInteger.valueOf(num2[i]))).multiply(BigInteger.valueOf(k)).add(result);
}
return convertToArray(result);
}
private static List<Integer> convertToArray(BigInteger result) {
List<Integer> rs=new ArrayList<>();
while (result.intValue()!=0){
int digit=result.mod(BigInteger.TEN).intValue();
rs.add(digit);
result = result.divide(BigInteger.TEN);
}
Collections.reverse(rs);
return rs;
}
public static String toString(int[] array){
StringBuilder sb=new StringBuilder();
for (int element:array){
sb.append(element);
}
return sb.toString();
}
#Test
public void testArray(){
int[] num1={2, 9, 8, 8, 9, 8};
int[] num2 = {3,6,3,4,5,8,9,1,2};
System.out.println(multiply(num1, num2));
}
}