Google Interview Question
Country: United States
The direction of the question was finally to create an output stream that is the subtraction of streams. String buffer is fine just for illustration. Good job!
It doesn't need to be, because c may be only 0,1 and therefore if c=1 b=7 a=8, the result is correctly 0.
b = (s_b.hasNext()) ? s_b.next() : 0;
this doesn't seem correct assumption
Lets say is a is '3' 5' '7' '4'
and b is '5'
you will actually provide result for
4753 -
5000
which is incorrect.
My guess is both stream will be of same length, otherwise it is difficult to calc subtraction
This works fine since:
a) streams are least to most significant digits and
b) s_b would be "done" before we start adding 0's.
Would this result in a string with 0's on the leading digits potentially?
s_a: 2018
s_b: 1024
result would be: "0994"
Which is probably fine but might be an edge case to consider.
It should be if (a - c >=b), you're code doesn't handle it well if there is no carry and the two digits are the same.
In your case try the streams 1 and 1, it will return 01 instead of 0. or in the case of streams 12 and 11 (which are actually the numbers 21 and 11) it will return 101 instead of 10.
String subtractStream(String s_a, Stream s_b) {
StringBuilder sb = new StringBuilder();
boolean carry = false;
while (s_a.hasNext()) {
int a = s_a.nextInt();
int b = 0;
if (s_b.hasNext()) {
b = s_b.nextInt();
}
if (carry) {
a--;
}
int result = (a - b);
if (result < 0) {
result += 10;
carry = true;
} else {
carry = false;
}
sb.append(result);
}
return sb.reverse().toString();
}
Very simple solution. Basically for every digit, subtract it, multiply it by the place value (it will be a multiple of 10), and add it to the total running sum.
String substract (Stream s_a, Stream s_b) {
int sum = 0;
int place = 1;
while(s_a.hasNext()) {
int a = s_a.next();
int b = (s_b.hasNext()) ? s_b.next();
int diff = (a - b)*place;
sum += diff;
place *= 10;
}
return Integer.toString(sum);
}
This seems very simple, am I missing something here?
function str_minus($str_a, $str_b) {
$i = $result = $minus = 0;
while (true) {
$aVal = fgetc($str_a);
$bVal = fgetc($str_b);
if (! $aVal && ! $bVal)
break;
$minus = intval($aVal ? $aVal : 0) - intval($bVal ? $bVal : 0);
$result += (abs($minus) * pow(10, $i++);
}
return strval($result);
}
public class rihs {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("please enter 2 Integers");
int st = sc.nextInt();
int st2 =sc.nextInt();
ArrayList<Integer> r = new ArrayList<Integer>();
ArrayList<Integer> r1 = new ArrayList<Integer>();
double y= stream_of_digits(st,r);
double t= stream_of_digits(st2,r1);
System.out.println(y-t);
}
public static double stream_of_digits(int n,ArrayList y) {
while (n > 0) {
y.add(n % 10);
n = n / 10;
}
return reverse(y);
}
public static double reverse(ArrayList re)
{
double h =(double)re.size();
//System.out.println("size:"+h);
Double r=0.0;
Iterator it = re.iterator();
while(it.hasNext())
{
int s = (int)it.next();
r=r+s*Math.pow(10,h-1);
// System.out.println(r);
h =h-1;
}
return r;
}
}
To me, it sounded like an LinkedList Question. Hence I implemented in LinkedList
public static MyLinkedList output = new MyLinkedList();
public static MyLinkedList stringToLinkedList(string a)
{
if (a.Length == 0)
return null;
else
{
output.AddLast(a.ElementAt(0) - '0');
}
stringToLinkedList(a.Substring(1));
return output;
}
public static string LinkedListSubtract(Node a, Node b)
{
StringBuilder str = new StringBuilder();
var carry = 0;
while (a != null && b != null)
{
if (a.data > b.data)
{
str.Insert(0, (a.data - b.data - carry));
carry = 0;
}
else if (a.data == b.data)
if (carry > 0)
str.Insert(0, (a.data - b.data + 10 - carry));
else
str.Insert(0, (a.data - b.data));
else
{
str.Insert(0, (a.data + 10 - b.data - carry));
carry = 1;
}
a = a.next;
b = b.next;
}
return str.ToString();
}
public static String findDifference(String aStream, String bStream){
StringBuilder result = new StringBuilder();
int index = 0;
boolean carry = false;
while(index < aStream.length()){
int a = aStream.charAt(index) - '0';
int b = 0;
if(index < bStream.length()){
b = bStream.charAt(index) - '0';
}
if(carry){
if(a == 0){
a = 10;
carry = true;
}
a-=1;
}
if(a < b){
a += 10;
carry = true;
}
result.append(a -b);
index++;
}
return result.reverse().toString();
}
import java.util.*;
public class HelloWorld{
public static void main(String []args){
List<Integer> s1= new ArrayList<>();
s1.add(2);
s1.add(0);
s1.add(4);
s1.add(8);
List<Integer> s2= new ArrayList<>();
s2.add(1);
s2.add(8);
s2.add(2);
s2.add(4);
System.out.println(f(s1, s2));
}
public static String f(List<Integer> s1, List<Integer> s2){
StringBuilder sb=new StringBuilder();
boolean flag=false;
int i=0;
while(i<s1.size()){
int a=s1.get(i);
int b;
if(i<s2.size()){
b=s2.get(i);
}
else{
b= 0;
}
i++;
if(flag){
if(a>0){
a-=1;
flag= false;
}
else{
a=9;
}
}
int c;
if(a>=b){
c= a-b;
}
else{
c= 10+a-b;
flag=true;
}
sb.insert(0, c);
}
return sb.toString();
}
}
Assuming both streams have equal number of digits, provided smaller number can have sufficient padded 0 to accommodate the difference, I will use this algo
While (GetNextA and GetNextB)
{
int result = a - b;
if (result < 0)
{
subtract one from previous digit in the result;
It should also handle the case of 0 being previous digit, iterate through first non zero
Add 10 to the current result digit and append it to the result
}
}
C++ Solution :
#include "stdafx.h"
#include <string>
#include <iostream>
#include <sstream>
#include <algorithm>
using namespace std;
char get_char_at_index(string str, size_t index)
{
size_t length = str.length();
if (index < length)
return str.at(index);
return '0';
}
string process(string a, string b)
{
size_t length = a.length();
bool carry = false;
ostringstream oss;
for (size_t i = 0; i < length; ++i)
{
char cSource = get_char_at_index(a, i);
char cTarget = get_char_at_index(b, i);
if (carry) {
cSource -= 1;
}
char result = cSource - cTarget;
if (result < 0)
{
result = result + 10;
carry = true;
}
else {
carry = false;
}
oss << (char)(result + '0');
}
string rev = oss.str();
reverse(rev.begin(), rev.end());
return rev;
}
#include "stdafx.h"
#include <string>
#include <iostream>
#include <sstream>
#include <algorithm>
using namespace std;
char get_char_at_index(string str, size_t index)
{
size_t length = str.length();
if (index < length)
return str.at(index);
return '0';
}
string process(string a, string b)
{
size_t length = a.length();
bool carry = false;
ostringstream oss;
for (size_t i = 0; i < length; ++i)
{
char cSource = get_char_at_index(a, i);
char cTarget = get_char_at_index(b, i);
if (carry) {
cSource -= 1;
}
char result = cSource - cTarget;
if (result < 0)
{
result = result + 10;
carry = true;
}
else {
carry = false;
}
oss << (char)(result + '0');
}
string rev = oss.str();
reverse(rev.begin(), rev.end());
return rev;
}
C++ Solution :
#include "stdafx.h"
#include <string>
#include <iostream>
#include <sstream>
#include <algorithm>
using namespace std;
char get_char_at_index(string str, size_t index)
{
size_t length = str.length();
if (index < length)
return str.at(index);
return '0';
}
string process(string a, string b)
{
size_t length = a.length();
bool carry = false;
ostringstream oss;
for (size_t i = 0; i < length; ++i)
{
char cSource = get_char_at_index(a, i);
char cTarget = get_char_at_index(b, i);
if (carry) {
cSource -= 1;
}
char result = cSource - cTarget;
if (result < 0)
{
result = result + 10;
carry = true;
}
else {
carry = false;
}
oss << (char)(result + '0');
}
string rev = oss.str();
reverse(rev.begin(), rev.end());
return rev;
}
C# solution using Stream; Stream B could have less digits that stream A
public string SubstractNumber(Stream sa, Stream sb)
{
int carry = 0;
StringBuilder result = new StringBuilder();
int a, b;
while((a = sa.ReadByte()) != -1)
{
b = sb.ReadByte();
if (b == -1)
b = 0;
b += carry;
int diff = a - b;
carry = (diff < 0) ? 1 : 0;
if (carry == 1)
diff = 10 + diff;
result.Insert(0, diff);
}
return result.ToString();
}
function subtract(A, B) {
var result = [];
var borrow = false;
for(var i = 0; i < Math.max(A.length, B.length); i++) {
var n1 = A.length > i ? A[i] : 0;
var n2 = B.length > i ? B[i] : 0;
var x = n1 - n2 - (borrow ? 1 : 0);
if(x < 0) {
x += 10;
borrow = true;
} else {
borrow = false;
}
result.push(x);
}
return result.reverse().join('');
}
The question didn't say that the result couldn't be stored in memory, but if s_a and s_b can't, then it's possible that we need to read/write the result to disk rather than a StringBuffer.
- Jason May 30, 2015