Friday, September 14, 2007

Java: highlight and show a particular row/cell in JTable inside JScrollPane

1. When we want to highlight one particular row in a JTable, we could call:
getTable().setRowSelectionInterval(i, i);


2. When we want to show a particular row/cell in a JTable inside a JScrollPane, we could call,

getTable().scrollRectToVisible(getTable().getCellRect(row, 0, true));

But it doesn't work so well if we overwrite the DefaultTableCellRenderer.

Java: create a table that a cell can contains multilines.

By default, the container in a JTable cell for a string is a JTextField object that only show all the content in one line. Sometimes, we need to present multi-lines in one cell, so we have to overwrite the cell handle object. Here is a sample for it.

The sequence is that overwrite the abstractTableModel, then overwrite the DefaultTableCellRender.

private DefaultTableModel getLogModel(){
if(logTblModel == null){
logTblModel = new DefaultTableModel() {
public boolean isCellEditable(int row, int colum) {
return false;
}
};

for(TITLE t : TITLE.values()){
logTblModel.addColumn(t.getName());
}
}
return logTblModel;
}


private JTable getTblLogRec() {
if (tblLogRec == null) {
tblLogRec = new JTable(getLogModel());
tblLogRec.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
tblLogRec.getColumn(TITLE.TIME.getName()).setPreferredWidth(100);
tblLogRec.getColumn(TITLE.LEVEL.getName()).setPreferredWidth(50);
tblLogRec.getColumn(TITLE.MESSAGE.getName()).setPreferredWidth(375);
tblLogRec.getColumnModel().getColumn(TITLE.MESSAGE.ordinal()).setCellRenderer(new DefaultTableCellRenderer() {
private JTextPane _sumaryTxtPane;
public Component getTableCellRendererComponent(
JTable table, Object value, boolean isSelected,
boolean hasFocus, int row, int column) {
getSumaryTxtPane().setText((String) value);
TableColumnModel columnModel = table
.getColumnModel();
getSumaryTxtPane().setSize(
columnModel.getColumn(column).getWidth(),
100000);
int heightWanted = (int) getSumaryTxtPane()
.getPreferredSize().getHeight();
if (heightWanted != table.getRowHeight(row)) {
table.setRowHeight(row, heightWanted);
}
if(isSelected){
getSumaryTxtPane().setBackground(getTblLogRec().getSelectionBackground());
}else{
getSumaryTxtPane().setBackground(getTblLogRec().getBackground());
}
return getSumaryTxtPane();
}

private JTextPane getSumaryTxtPane() {
if (null == _sumaryTxtPane) {
_sumaryTxtPane = new JTextPane();
}
return _sumaryTxtPane;
}
});
}
return tblLogRec;
}
}

Monday, August 6, 2007

Java: catch a system signal

In Java, here is an example to catch a system signal:

=========================================================================
import sun.misc.Signal;
import sun.misc.SignalHandler;
import java.util.Random;

public class SignalTerm {
public static void main(String[] args) {
try{
System.out.println("System start.");
DiagSignalHandler.install("INT");
ThreadGroup tg = new ThreadGroup("AAA");
MyThread mt[] = new MyThread[10];
for(int i=0; i < mt.length; i++){
mt[i] = new MyThread(tg,i);
mt[i].start();
}
for(int i=0; i < mt.length; i++){
mt[i].join();
}
System.out.println("System exit.");

} catch(Exception e){
System.out.println("exception: " + e.getMessage());
e.printStackTrace();
}
}
}

class MyThread extends Thread {
private int threadcnt;
public MyThread(ThreadGroup tg, int n){
super(tg, "My" + n);
threadcnt = n;
}
public void run(){
try {
System.out.println("In thread " + threadcnt);
while(true) sleep(1000);

} catch (InterruptedException e) {
Random ran = new Random();
int rn = ran.nextInt(20);
System.out.println("Thread " + threadcnt + " is shuting down. Please wait " + rn + " seconds.");
try {
sleep(rn* 1000);

} catch (InterruptedException e1) {}
System.out.println("Thread " + threadcnt + " exit.");
}
}
}

//Diagnostic Signal Handler class definition
class DiagSignalHandler implements SignalHandler {
private SignalHandler oldHandler;

// Static method to install the signal handler
public static DiagSignalHandler install(String signalName) {
Signal diagSignal = new Signal(signalName);
DiagSignalHandler diagHandler = new DiagSignalHandler();
diagHandler.oldHandler = Signal.handle(diagSignal,diagHandler);
return diagHandler;
}

// Signal handler method
public void handle(Signal sig) {
System.out.println("Diagnostic Signal handler called for signal "+sig);
try {
// Output information for each thread
Thread[] threadArray = new Thread[Thread.activeCount()];
int numThreads = Thread.enumerate(threadArray);
System.out.println("Current threads:");
for (int i=0; i < numThreads; i++) {
System.out.println(" "+threadArray[i] + ", " + threadArray[i].getThreadGroup().getName());
if(threadArray[i].getThreadGroup().getName().equalsIgnoreCase("AAA")){
threadArray[i].interrupt();
}
}

for (int i=0; i < numThreads; i++) {
if((threadArray[i] != null) && (threadArray[i].getThreadGroup() != null) &&
(threadArray[i].getThreadGroup().getName().equalsIgnoreCase("AAA"))){
threadArray[i].join();
}
}

// Chain back to previous handler, if one exists
if ( oldHandler != SIG_DFL && oldHandler != SIG_IGN ) {
oldHandler.handle(sig);
}

} catch (Exception e) {
System.out.println("Signal handler failed, reason "+e);
e.printStackTrace();
}
}
}
=========================================================================

Heinz[2] mentioned the signal lists in different OSs:
Windows: ABRT, FPE, ILL, INT, SEGV, TERM

Solaris: ABRT, ALRM, BUS, CHLD, CONT, EMT, FPE, HUP, ILL, INT, IO, KILL, PIPE, POLL, PROF, PWR, QUIT, SEGV, STOP, SYS, TERM, TRAP, TSTP TTIN, TTOU, URG, USR1, USR2, VTALRM, WINCH, XCPU, XFSZ

References:

Chris White, Revelations on Java signal handling and termination, http://www.ibm.com/developerworks/ibm/library/i-signalhandling/
Dr. Heinz M. Kabutz, Switching off OS signals at runtime,
http://www.roseindia.net/javatutorials/
switching_off_os_signals_at_runtime.shtml

Java: construct a class with parameters in reflection

Here is a simple example for constructing a object with two parameters in Java Reflection:

=====================================================================
import java.lang.reflect.*;

public class LoadParamObject {
public LoadParamObject() {}

public LoadParamObject(int a, String b) {
System.out.println("a = " + a + " b = " + b);
}

public static void main(String args[]) {
try {
Class cls = Class.forName("LoadParamObject");
Class partypes[] = new Class[2];
partypes[0] = Integer.TYPE;
partypes[1] = String.class;
Constructor ct = cls.getConstructor(partypes);
Object arglist[] = new Object[2];
arglist[0] = new Integer(37);
arglist[1] = new String("BBB");
Object retobj = ct.newInstance(arglist);

} catch (Throwable e) {
System.err.println(e);
}
}
}
=====================================================================

The detail explanation please read below:
http://java.sun.com/developer/technicalArticles/ALT/Reflection/

Thursday, July 12, 2007

Getting the program name that is listening on a specified port

Sometimes we need to find out which program is listening on a specified port.

In Linux, we can use:
netstat -natlp

-n, --numeric don't resolve names
-a, --all, --listening display all sockets (default: connected)
< Socket >={-t|--tcp} {-u|--udp} {-w|--raw} {-x|--unix} --ax25 --ipx --netrom
-l, --listening display listening server sockets
-p, --programs display PID/Program name for sockets

In windows, we can use fport which can be downloaded in the internet.

Its official website: http://www.foundstone.com/us/resources-free-tools.asp

Friday, July 6, 2007

Java: a simple HTTP server sample

In JDK 6, it is very easy to create a HTTP server. Here is a sample in SDK 6.

===================================================
import java.io.IOException;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import com.sun.net.httpserver.spi.HttpServerProvider;
import com.sun.net.httpserver.HttpExchange;
import com.sun.net.httpserver.HttpHandler;
import com.sun.net.httpserver.HttpServer;


public class SimpleHttpServer {
public static void main(String[] args) throws Exception{
HttpServerProvider httpServerProvider = HttpServerProvider.provider();
InetSocketAddress addr = new InetSocketAddress(8888);
HttpServer httpServer = (HttpServer)httpServerProvider.createHttpServer(addr, 1);
httpServer.createContext("/mydemo/", new MyHttpHandler());
httpServer.setExecutor(null);
httpServer.start();
System.out.println("started");
}

static class MyHttpHandler implements HttpHandler{
public void handle(HttpExchange httpExchange) throws IOException {
String response = "Hello world!";
httpExchange.sendResponseHeaders(200, response.length());
OutputStream out = httpExchange.getResponseBody();
out.write(response.getBytes());
out.close();
}
}
}
===================================================

Website visited statistics

For counting the visited amount, first of all, add one configuration in config/environment.rb
RAILS_DEFAULT_LOGGER = Logger.new("#{RAILS_ROOT}/log/#{RAILS_ENV}.log", "daily")

1. get the request statistics
cat production.log.20070702|grep "200 OK"|wc -l

2. get the URL visited statistics
cat production.log.20070702 | grep "200 OK" | awk '{print $17}'|sort|uniq -c | sort -r -n > stat.log

Wednesday, July 4, 2007

Java: Send a Http Request

Here is the sample code for sending a http request using Java Library

===================================================
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.io.OutputStream;

public class HttpTest extends Thread{
public static void main(String[] args) {
try {
URL u = new URL("http://192.168.1.10:80/http/incoming");
HttpURLConnection uc = (HttpURLConnection) u.openConnection();
uc.setRequestMethod("POST");
uc.setRequestProperty("Host" , "1.1.1.1");
uc.setRequestProperty("Accept", "*/*");
uc.setRequestProperty("Content-Type", "application/octet-stream");
uc.setDoOutput(true);
uc.connect();
OutputStream os = uc.getOutputStream();
os.write("123456".getBytes());
uc.disconnect();
System.out.println("Response code: " + uc.getResponseCode());
String key = null;
for (int i=1; ((key = uc.getHeaderFieldKey(i))!=null); i++) {
System.out.println(key + ": " + uc.getHeaderField(key));
}
} catch (IOException e) {
e.printStackTrace();
}
}
}

===================================================

In my opinion, if it was a very simple application such as only sending a simple message via HTTP protocol, it was better to implement by yourself because it is more flexible and more efficient. I did it in my current project. However, there is a risk for implement by yourself. It's that Java Sock library is not thread safe. Be careful.

Here is a HTTP message sample:
==============================================
POST /http/incoming HTTP/1.1
Accept: */*
Content-Length: 6
Host: 192.168.1.10:80
Content-Type: application/octet-stream
Date: 2007-07-04 12:12:12

123456
==============================================

Wednesday, June 27, 2007

Getting environment values

There are two ways for getting the environment values in Java:

1. We can use System.getProperty(systemPropertyString) to retrieve the values, such as java.version, java.home, os.name, user.name, user.home, user.dir, java.io.tmpdir etc;

2. Use System.getenv to enumerate all the system environment:

==============================================================
import java.util.*;

public class ListEnv {
public static void listAllEnv(){
Map variables = System.getenv();
Set variableNames = variables.keySet();

Iterator nameIterator = variableNames.iterator();

for(int index=0; index < variableNames.size(); index++){
String name = (String) nameIterator.next();
String value = (String) variables.get(name);
System.out.println(name + "=" + value);
}
}

public static void main(String[] args) {
listAllEnv();
}
}
==============================================================

Tuesday, June 26, 2007

Q11: number composition

Q: How many three digit numbers can you generate with 1, 2, 3, 4. The numbers are not duplicated and each number doesn't have duplicate digits.

A:

===========================================
import java.util.Vector;

public class NumberComposition {
private static Vector nums = new Vector();

public static void generateNumbers(){
int num;

for(int i=1; i <= 4; i++){
num =0;
for(int j=1; j <= 4; j++){
for(int k=1; k <= 4; k++){
if((i!=j) && (i!=k) && (j!=k)){
num = i* 100 + j*10 + k;
nums.add(num);
}else continue;
}
}
}
}

public static int getNumberCounter(){
return nums.size();
}

public static void printNumbers(){
for(int i=0; i < nums.size(); i++){
System.out.print(nums.get(i) + " ");
}
}

public static void main(String[] args) {
generateNumbers();
System.out.println("Total number: " + getNumberCounter());
printNumbers();
}
}
==========================================

result:
Total number: 24
123 124 132 134 142 143 213 214 231 234 241 243 312 314 321 324 341 342 412 413 421 423 431 432

Tuesday, June 19, 2007

Java mail SMTP sample code

This sample code demonstrates the minimum Java code for using regular SMTP service and GMail SMTP service.

First of all, we download the Java Activation Framework and JavaMail packages.

Sample code is followed:

===============================================================

import java.security.Security;
import java.util.Date;
import java.util.Properties;

import javax.mail.Authenticator;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.NoSuchProviderException;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.AddressException;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;

public class AlarmMail {
public void sendGMail() {
Security.addProvider(new com.sun.net.ssl.internal.ssl.Provider());
final String SSL_FACTORY = "javax.net.ssl.SSLSocketFactory";

// Get a Properties object, and set the parameters of mail service
Properties props = new Properties();
props.setProperty("mail.smtp.host", "smtp.gmail.com");
props.setProperty("mail.smtp.socketFactory.class", SSL_FACTORY);
props.setProperty("mail.smtp.socketFactory.fallback", "false");
props.setProperty("mail.smtp.port", "465");
props.setProperty("mail.smtp.socketFactory.port", "465");
props.put("mail.smtp.auth", "true");
final String username = "shuzhanqiang@gmail.com";
final String password = "******";
Session session = Session.getDefaultInstance(props,
new Authenticator() {
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(username, password);
}
});

session.setDebug(true);

// -- Create a new message --
Message msg = new MimeMessage(session);

// -- Set the FROM, TO, and Mail contain fields --
try {
msg.setFrom(new InternetAddress(username));
msg.setRecipients(Message.RecipientType.TO, InternetAddress.parse(
"shu_zhq@yahoo.com", false));
msg.setSubject("Hello");
msg.setText("Hello");
msg.setSentDate(new Date());
System.out.println("Start sending");
Transport.send(msg);
} catch (AddressException e) {
e.printStackTrace();

} catch (MessagingException e) {
e.printStackTrace();

}

System.out.println("Message sent.");
}

private String mailhost = "mail.abc.com";
private String user = "qiang@abc.com";
private String password = "123456";
private String from, to, cc, bcc;
private String subject;
private String text;
private String mailer = "smtpsend";
private boolean ssl = false;
private boolean verbose;

public void sendMsg() {
try {
InternetAddress[] address = null;

// Get a Properties object, and set the parameters of mail service
Properties props = new Properties();
props.put("mail.smtp.host", mailhost);
props.setProperty("mail.smtp.port", "25");
props.put("mail.smtp.auth", "true");
javax.mail.Session sessmail = javax.mail.Session.getInstance(props);
sessmail.setDebug(true);
MimeMessage msg = new MimeMessage(sessmail);
msg.setFrom(new InternetAddress(user));

address = InternetAddress.parse(to, false);
msg.setRecipients(Message.RecipientType.TO, address);

msg.setSubject(subject);
msg.setSentDate(new Date());
msg.setText(text, "UTF-8");
Transport transport = sessmail.getTransport("smtp");
transport.connect(mailhost, user, password);
transport.sendMessage(msg, msg.getAllRecipients());
transport.close();
} catch (AddressException e) {
e.printStackTrace();

} catch (NoSuchProviderException e) {
e.printStackTrace();

} catch (MessagingException e) {
e.printStackTrace();

}

}


public static void main(String[] args) {
AlarmMail am = new AlarmMail();
am.setFrom("shu_zhq@gmail.com");
am.setTo("shu_zhq@yahoo.com");
am.setSubject("Help");
am.setText("Help.");
am.sendMsg();

am.sendGMail();
}

public String getBcc() {
return bcc;

}

public void setBcc(String bcc) {
this.bcc = bcc;

}

public String getCc() {
return cc;

}

public void setCc(String cc) {
this.cc = cc;

}

public String getFrom() {
return from;

}

public void setFrom(String from) {
this.from = from;

}

public String getMailer() {
return mailer;

}

public void setMailer(String mailer) {
this.mailer = mailer;

}

public String getMailhost() {
return mailhost;

}

public void setMailhost(String mailhost) {
this.mailhost = mailhost;

}

public String getPassword() {
return password;

}

public void setPassword(String password) {
this.password = password;

}

public boolean isSsl() {
return ssl;

}

public void setSsl(boolean ssl) {
this.ssl = ssl;

}

public String getSubject() {
return subject;

}

public void setSubject(String subject) {
this.subject = subject;

}

public String getText() {
return text;

}

public void setText(String text) {
this.text = text;

}

public String getTo() {
return to;

}

public void setTo(String to) {
this.to = to;

}

public String getUser() {
return user;

}

public void setUser(String user) {
this.user = user;

}

public boolean isVerbose() {
return verbose;

}

public void setVerbose(boolean verbose) {
this.verbose = verbose;

}

}

Thursday, June 14, 2007

DNS Configuration in Fedora 4

This is only to set up a DNS environment for an application testing, so it only setup a simple domain look up function, and doesn't use so much functions, such as bind-chroot

DNS setup steps:

1. Design the mapping between domain name and IP address. Here, I use zhanqiang.net and 192.168.1.110;

2. Check if BIND(Berkeley Internet Name Domain) has been installed: rpm -qa | grep bind

3. Add some lines in /etc/named.conf

change
=======================================
zone "0.in-addr.arpa" IN {
type master;
file "named.zero";
allow-update { none; };
};
include "/etc/rndc.key";

=======================================
to
=======================================
zone "0.in-addr.arpa" IN {
type master;
file "named.zero";
allow-update { none; };
};

zone "zhanqiang.net" IN {
type master;
file "zhanqiang.net.zone";
allow-update { none; };
};

include "/etc/rndc.key";
=======================================

4. create and edit /var/named/zhanqiang.net.zone
=======================================
$TTL 86400
@   IN  SOA   dns.zhanqiang.net.  root.zhanqiang.net. (
1997022700 ; Serial
28800 ; Refresh
7000 ; Retry
1800000 ; Expire
86400 ) ; Minimum

@  IN  NS    dns.zhanqiang.net.
@  IN MX 10   dns.zhanqiang.net.
dns    IN A 192.168.1.110
www    IN CNAME     dns
=======================================

5. restart named(DNS) service: service named restart

6. check firewall if the port 53 has been blocked;

7. run neat or edit /etc/resolve.conf for changing the network card DNS setting in order to use the DNS service in 192.168.1.110

8. test the DNS with ping, host, and nslookup commands

Now it is done.

Wednesday, June 13, 2007

Q10: Bouncing Ball

Q: a ball is dropped from 100 meters and bounce back to half of previous height. How many meters does it pass when it hits the ground at 10th time, and the height of it 10th bounce back?

A:


public class BallBounce {
/**
* Because the height is half of the previous one each bounce back,
* the height is divided by 2 each time.
* @param initHeight the initial height
* @param times the number of bounce back
* @return the height of bounce
*/
public static float getHeight(float initHeight, int times){
for(int i=0; i< times; i++){
initHeight /= 2;
}
return initHeight;
}

/**
* When ball hits ground n times, it bounces back n-1 time.
* Therefore, it passes initHeight plus the multiplication of 2 and height of each bounce.
* @param initHeight the initial height
* @param times the number that ball hits the ground
* @return the meters of the ball passed
*/
public static float getBallPass(float initHeight, int hitTimes){
float p = initHeight;
for(int i=0; i<(hitTimes-1); i++){
p += getHeight(initHeight, i+1)*2;
}
return p;
}

public static void main(String[] args) {
int times = 5;
System.out.println("When the ball hits 10th ground, it passes " + getBallPass(100, times) + " meters, and it bounces back " + getHeight(100, times));
}
}

result:
When the ball hits 10th ground, it passes 299.60938 meters, and it bounces back 0.09765625.

Monday, June 11, 2007

Q9: Perfect Number

Q: find out all perfect numbers that are less than 1,000.

a perfect number is defined as an integer which is the sum of its proper positive divisors, that is, the sum of the positive divisors not including the number. For example, the first perfect number is 6, because 1, 2 and 3 are its proper positive divisors and 1 + 2 + 3 = 6. Definition is from wikipedia.org

A:
import java.util.Vector;

public class PerfectNumber {
private static Vector v ;

private static void getAllFactors(int n){
v = new Vector();
if(n <= 2) return;
v.add(1);
int sqrt = (int)Math.pow(n, 0.5)+1;
for(int i=2; i < sqrt; i++){
if((n%i) == 0){
v.add(i);
v.add(n/i);
}
}
}

private static boolean isPerfectNumber(int num){
getAllFactors(num);
int sum = 0;
for(int i=0; i < v.size(); i++){
sum += v.get(i);
}
// System.out.println(num + " sum: " + sum);
if(sum == num) return true;
return false;
}

public static void printPerfectNumber(int range){
for(int i=1; i < range; i++){
if(isPerfectNumber(i)){
System.out.print(i + ", ");
}
}
}
public static void main(String[] args) {
System.out.println("Perfect numbers between 0 and 1000: ");
PerfectNumber.printPerfectNumber(1000);
}
}

Result:
Perfect numbers between 0 and 1000:
6, 28, 496,

Thursday, June 7, 2007

Q8: sum calculation

Q: calculate the sum of s in s = a + aa + a...a. a is a number. The last number is a a digits number. For example, a is 5, then the formula is s = 5 + 55 + 555 + 5555 + 55555.

A:

public class Sum {
private static int getNumber(int a, int len){
int num =0;
for(int i=1; i<=len; i++){
num = num * 10 + a;
}
System.out.println("num " + len +": " + num);
return num;
}

public static int getSum(int a){
int sum =0;
for(int i=1; i<=a; i++){
sum += getNumber(a, i);
}
return sum;
}
public static void main(String[] args) {
System.out.println("Sum for 5: " + Sum.getSum(5));
}
}

result:
num 1: 5
num 2: 55
num 3: 555
num 4: 5555
num 5: 55555
Sum for 5: 61725

Wednesday, June 6, 2007

Q7: Input statistics

Q: Counting the quantity of letters, numbers, space, and others in a input line.

A:

import java.util.Scanner;

public class InputCounting {
public static int countLetters(String is){
byte b[] = is.getBytes();
int cnt = 0;
for(int i=0; i < b.length; i++){
if(Character.isLetter(b[i])) cnt++;
}
return cnt;
}

public static int countNumbers(String is){
byte b[] = is.getBytes();
int cnt = 0;
for(int i=0; i < b.length; i++){
if(Character.isDigit(b[i])) cnt++;
}
return cnt;
}

public static int countSpaces(String is){
byte b[] = is.getBytes();
int cnt = 0;
for(int i=0; i < b.length; i++){
if(Character.isSpaceChar(b[i])) cnt++;
}
return cnt;
}

public static int countOthers(String is){
byte b[] = is.getBytes();
int cnt = 0;
for(int i=0; i < b.length; i++){
if(!(Character.isSpaceChar(b[i]) ||
Character.isDigit(b[i]) ||
Character.isLetter(b[i])))
cnt++;
}
}
return cnt;
}

public static void main(String[] args) {
Scanner s = new Scanner(System.in);
String input;
while(true){
System.out.print("Please input the counted String: ");
input = s.nextLine();
if(input.equalsIgnoreCase("Quit")) break;
System.out.println("Letter quantity: " + InputCounting.countLetters(input));
System.out.println("Number quantity: " + InputCounting.countNumbers(input));
System.out.println("Space quantity: " + InputCounting.countSpaces(input));
System.out.println("Others quantity: " + InputCounting.countOthers(input));
}
}
}

result:
Please input the counted String: What are the counters for "123456"?
Letter quantity: 21
Number quantity: 6
Space quantity: 5
Others quantity: 3
Please input the counted String: Quit

Tuesday, June 5, 2007

Q6: Lowest common denominator and Greatest common divisor

Q: find the Lowest Common Denominator(LCD) and the Greatest Common Divisor(GCD) for two given integers.

The lowest common denominator or least common denominator (abbreviated LCD) is the least common multiple of the denominators of a set of vulgar fractions.

The greatest common divisor (gcd), sometimes known as the greatest common factor (gcf) or highest common factor (hcf), of two non-zero integers, is the largest positive integer that divides both numbers without remainder.

The definitions are from Wikipedia.org

A:

public class GcdAndLcm {
// This is using Euclidean algorithm.
public static int getGreatestCommonDivisor(int a, int b){
// make sure that a is greater than b
if(b > a){
int c = a; a = b; b = c;
}

if((a % b) == 0) return b;
else if( (a % b) == 1) return 1;
else return getGreatestCommonDivisor(b, (a%b));
}

public static int getLeastCommonMultiple(int a, int b){
return (a * b / getGreatestCommonDivisor(a, b));
}

public static void main(String[] args) {
System.out.println("Greatest Common Divisor for 84 and 18 is " + GcdAndLcm.getGreatestCommonDivisor(84, 18));
System.out.println("Least Common Multiple for 84 and 18 is " + GcdAndLcm.getLeastCommonMultiple(84, 18));
}
}

result:
Greatest Common Divisor for 84 and 18 is 6
Least Common Multiple for 84 and 18 is 252

Monday, June 4, 2007

Q5: Mark Rank

Q: Ranking a mark:
1. Greater than or equal to 90, it is A;
2. Between 60 and 89, it is B;
3. Less than 60, it is C.


A:

public class MarkRank {
public static char rankMark(int mark){
if(mark >= 90) return 'A';
else if((mark <=89) && (mark >=60)) return 'B';
else return 'C';
}

public static void main(String[] args) {
System.out.println("Mark 95: " + MarkRank.rankMark(95));
System.out.println("Mark 78: " + MarkRank.rankMark(78));
System.out.println("Mark 59: " + MarkRank.rankMark(59));
}
}

Sunday, June 3, 2007

Q4: Integer factorization.

Q: factorize a given integer. For example: 90 = 2*3*3*5;

A:
Assuming a number n to be factorized. following steps:
1. from 1 to n, find the smallest prime number a by which n is divided;
2. if a equal to n, then exit;
3. if n is divided by a, then performs the division continuously, and the result is assigned to n;
4. if n is not divided by a, try the next number a = a + 1, and repeat 2 to 4;


public class IntegerFactoring {
private static int getFactor(int num, int startpoint){
if(num <= 1) return 1;
for(int i=startpoint+1; i<=num; i++){
if((num % i) == 0) return i;
}
return 1;
}

public static void printFactoring(int n){
int f = 1;
f=getFactor(n, f);
System.out.print(n + "=" + f);
n = n/f;
f--;
while((f=getFactor(n, f)) !=1){
while(n%f ==0){
n = n/f;
System.out.print("*" + f);
}
}
}

public static void main(String[] args) {
IntegerFactoring.printFactoring(90);
}
}

result:
90=2*3*3*5

Saturday, June 2, 2007

Q3: Armstrong Number(Narcissistic number)

Q: Print out all Narcissistic numbers between 100 and 999.

In number theory, a narcissistic number or pluperfect digital invariant (PPDI) or Armstrong number is a number that in a given base is the sum of its own digits to the power of the number of digits.

For example, the decimal (Base 10) number 153 is an Armstrong number, because:

1³ + 5³ + 3³ = 153
A:
public class Armstrong {
private static boolean isArmstrong(int n){
int base = n;
int size = Integer.toString(n).length();
int sum = 0, d=0;

for(int i=0; i < size; i++){
d = base %10;
base /=10;
sum += Math.pow(d, size);
}
if(sum == n) return true;
else return false;
}

public static int getArmstrongQuantity(int root, int floor){
int cnt =0;
for(int i=root; i < floor; i++){
if(isArmstrong(i)){
System.out.print(i + ", ");
cnt++;
}
}
System.out.println();
return cnt;
}

public static void main(String[] args) {
System.out.println("There are " +
Armstrong.getArmstrongQuantity(100, 999) +
" armstrong numbers between 100 and 999.");
}
}

result:
153, 370, 371, 407,
There are 4 armstrong numbers between 100 and 999.

Q2: Prime numbers between 100 and 200

Q: How many prime numbers are there between 100 and 200?

A:

public class PrimeNumber {
private static boolean isPrimeNumber(int num){
int e = (int)Math.pow(num, 0.5) + 1;
for(int i = 2; i< e; i++){
/* detect if the number is divided by a integer */
if( (num%i) == 0)
return false;
}
return true;
}
}

public static int getPrimeNumberQuantity(int root, int floor){
if(floor < 2) return 0;

int q = 0;
for(int i=root; i < floor; i++){
if(isPrimeNumber(i)){
q++;
System.out.print(i + ", ");
}
}
System.out.println();
return q;

}

public static void main(String[] args) {

int m = PrimeNumber.getPrimeNumberQuantity(100, 200);
System.out.println("There are " + m + " prime numbers between 100 and 200.");
}
}


Result:

101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199,
There are 21 prime numbers between 100 and 200.

Thursday, May 31, 2007

Q1: multiplying rabbits

Question: A newly born rabbit is capable of reproducing at one month old (when it matures). Suppose the rabbit never dies, and it continues reproducing one new rabbit every month. So, when the rabbit is born, it has one member in its own family. After a month, it matures, and by the second month it adds a new born member to its family. In the third month, the rabbit produces another offspring; its first child also matures and will be ready to have an offspring in the next month. How many pairs of rabbits can be produced in a year from a single pair?

Answer: Let us write down the sequence of the rabbit number: 1, 1, 2, 3, 5, 8, 13 ... . It is a Fibonacci numbers.

The following code is the implementation in Java.

public class Fibonacci {
public static int getFibonacci(int n){
if(n < 0) return 0;
if((n == 0) || (n == 1)) return 1;
return getFibonacci(n-1) + getFibonacci(n-2);
}

public static void main(String[] args) {
for(int n=-1; n < 13; n++)
System.out.println(n + ": \t" + Fibonacci.getFibonacci(n));
}
}
}

The result:
-1: 0
0: 1
1: 1
2: 2
3: 3
4: 5
5: 8
6: 13
7: 21
8: 34
9: 55
10: 89
11: 144
12: 233

Monday, May 28, 2007

RoR: lighttpd proxy setting

For accessing other servers' resources transparently, setting up the web server to support reverse proxy.

In lighttpd, the steps:
1. add 'mod_proxy' in server module group;
2. set up the server as:
=================================================
$HTTP["host"] == "rails.qiang.com" {
server.document-root = "/rails/sample/public"
url.rewrite = ( "^/$" => "index.html", "^([^.]+)$" => "$1.html" )
server.error-handler-404 = "/dispatch.fcgi"
server.errorlog = "/rails/sample/lighttpd.log"
fastcgi.server = ( ".fcgi" =>
( "localhost" =>
(
"min-procs" => 2,
"max-procs" => 4,
"socket" => "/tmp/stage-fcgi.socket",
"bin-path" => "/rails/sample/public/dispatch.fcgi",
"bin-environment" => ("RAILS_ENV" => "rail")
)
))

proxy.server = ( "/other" => ( "other" => ("host" => "1.1.1.1/other", "port" => 80)))
}
=================================================

For apache, please read the followed link: http://www.apachetutor.org/admin/reverseproxies.

Friday, May 18, 2007

RoR: unexpected nil when trying to parse a query string

While sending a HTTP post message that contains a substring '&&' in the body to a ruby on rails application, there is a error reported:

==================================================
You have a nil object when you didn't expect it!
You might have expected an instance of Array.
The error occurred while evaluating nil.include?
/public/../config/../vendor/rails/actionpack/lib/action_controller/cgi_ext/cgi_methods.rb:49:in `parse_request_parameters'
/public/../config/../vendor/rails/actionpack/lib/action_controller/cgi_ext/cgi_methods.rb:47:in `parse_request_parameters'
/public/../config/../vendor/rails/actionpack/lib/action_controller/cgi_process.rb:71:in `request_parameters'
/public/../config/../vendor/rails/actionpack/lib/action_controller/request.rb:13:in `parameters'
/public/../config/../vendor/rails/actionpack/lib/action_controller/session_management.rb:122:in `set_session_options_without_components'
/public/../config/../vendor/rails/actionpack/lib/action_controller/components.rb:178:in `set_session_options'
/public/../config/../vendor/rails/actionpack/lib/action_controller/session_management.rb:116:in `process'
/public/../config/../vendor/rails/railties/lib/dispatcher.rb:38:in `dispatch'
/public/../config/../vendor/rails/railties/lib/fcgi_handler.rb:150:in `process_request'
/public/../config/../vendor/rails/railties/lib/fcgi_handler.rb:54:in `process!'
/usr/lib/ruby/site_ruby/1.8/fcgi.rb:612:in `each_cgi'
/usr/lib/ruby/site_ruby/1.8/fcgi.rb:609:in `each_cgi'
/public/../config/../vendor/rails/railties/lib/fcgi_handler.rb:53:in `process!'
/public/../config/../vendor/rails/railties/lib/fcgi_handler.rb:23:in `process!'
/public/dispatch.fcgi:24
==================================================

The error occurred because '&' is the separator of different name/value pair in a message body, such as "name1=value1&name2=value2", and rails framework doesn't handle the string "&&" properly. According to a bug report and its patch in rubyonrails.org (http://dev.rubyonrails.org/ticket/5714), we need to change "/vendor/rails/actionpack/lib/action_controller/cgi_ext/cgi_methods.rb" line 47 from

==================================================
for key, value in params
value = [value] if key =~ /.*\[\]$/
unless key.include?('[')
# much faster to test for the most common case first (GET)
# and avoid the call to build_deep_hash
parsed_params[key] = get_typed_value(value[0])
else
build_deep_hash(get_typed_value(value[0]), parsed_params, get_levels(key))
end
end
==================================================

to

==================================================
for key, value in params
if (not key.nil?)
value = [value] if key =~ /.*\[\]$/
unless key.include?('[')
# much faster to test for the most common case first (GET)
# and avoid the call to build_deep_hash
parsed_params[key] = get_typed_value(value[0])
else
build_deep_hash(get_typed_value(value[0]), parsed_params, get_levels(key))
end
end
end
==================================================