Java算法之進制轉換的奧義

在計算如此方便的今天,又有多少人知道在一個計算器後面有多少路要走嗎?你的手指輕輕一點,後臺就有成千上百條代碼在幫你工作,今天,就來體驗一下計算器中的進制轉換功能。

對於進制轉換,大家並不陌生,在機器或者程序中常用的進制也就是二進制,八進制,十進制,十六進制...。而對於我們,其實接觸的最多其實是十進制,二進制一般用於機器中表示,在數電,數邏,計算機組成,信息傳輸中等等使用頻繁。關於其他進制的使用,這裏就不再一一闡述了。

今天要完成的功能是對於任何一個數,當然,是在機器所能表示範圍之中,完成對於2-16進制中任何一個進制的轉換。這裏就不討論1進制了,沒有意義。現在我們約定一下功能:

輸入:

在第一行輸入兩個數字,分別是要計算的數字和要轉換的進制

輸出:

輸出轉換結果,對於11-16進制。按照16進制的規則,就是10用A表示,11用B表示....

分析:

首先,我們打開電腦自帶的計算器功能,在查看中找到程序員專屬的這一個...,如圖所示,只提供了常見的進制轉換功能。

,寫程序迫在眉睫啊,因爲我們還有 5 6 7 9 11 12 13 14 15進制沒實現呢。

首先,關於進制轉換的代碼,之前學計算機組成原理時已經寫過很多次了 ,那時候僅限於二進制,如果要改成其它進制其實基本上也就是換湯不換藥了。但是上學期又學了算法。就琢磨着,用個算法來實現,最後決定了,用最粗暴的方法---暴力破解法(也就是枚舉)。

開始,其思想是將輸入的數值放在數組中,通過按位加權求和操作代碼來枚舉所有結果,如果遇到正確答案,則給予輸出。

既然要暴力破解,那肯定少不了循環的操作了,多少層循環是個關鍵,這裏不得不考慮到極端情況,那就是2進制的情況,需要的表示位是最多的,我在這裏假設一個約束,輸入的數值最大不超過10000,在此條件下,若轉換爲2進制,則需要15個二進制位來表示,因此最壞的情況就是15層循環的嵌套,利用CV大法寫好循環後,還有一個超級長的按位加權求和操作,最後將正確答案保存至數組進行輸出。代碼如下。


import java.util.Scanner;
public class radixTransform
{
//	private static String ANSWER="";
	private static int RADIX;
	private static char SYMBOL;
	private static int DECIMAL;
	private static int ANSWER[]=new int[15];
	public  radixTransform(int RADIX,char SYMBOL,int DECIMAL)
	{
		radixTransform.RADIX=RADIX;
		radixTransform.SYMBOL=SYMBOL;
		radixTransform.DECIMAL=DECIMAL;
	}
	public static void RadixTrans(int value[])
	{
		int decimalValue=0;
		for(int a=0;a<radixTransform.RADIX;a++)
		{
			for(int b=0;b<radixTransform.RADIX;b++)
			{
				for(int c=0;c<radixTransform.RADIX;c++)
				{
					for(int d=0;d<radixTransform.RADIX;d++)
					{
						for(int e=0;e<radixTransform.RADIX;e++)
						{
							for(int f=0;f<radixTransform.RADIX;f++)
							{
								for(int g=0;g<radixTransform.RADIX;g++)
								{
									for(int h=0;h<radixTransform.RADIX;h++)
									{
										for(int i=0;i<radixTransform.RADIX;i++)
										{
											for(int j=0;j<radixTransform.RADIX;j++)
											{
												for(int k=0;k<radixTransform.RADIX;k++)
												{
													for(int l=0;l<radixTransform.RADIX;l++)
													{
														for(int m=0;m<radixTransform.RADIX;m++)
														{
															for(int n=0;n<radixTransform.RADIX;n++)
															{
																for(int o=0;o<radixTransform.RADIX;o++)
																{
																	System.out.println("RUNING******");
																		decimalValue=(int) (a*Math.pow(radixTransform.RADIX,14)+b*Math.pow(radixTransform.RADIX,13)+c*Math.pow(radixTransform.RADIX,12)+d*Math.pow(radixTransform.RADIX,11)+e*Math.pow(radixTransform.RADIX,10)+f*Math.pow(radixTransform.RADIX,9)+g*Math.pow(radixTransform.RADIX,8)+h*Math.pow(radixTransform.RADIX,7)+i*Math.pow(radixTransform.RADIX,6)+j*Math.pow(radixTransform.RADIX,5)+k*Math.pow(radixTransform.RADIX,4)+l*Math.pow(radixTransform.RADIX,3)+m*Math.pow(radixTransform.RADIX,2)+n*Math.pow(radixTransform.RADIX,1)+o*Math.pow(radixTransform.RADIX,0));
																		if(decimalValue==radixTransform.DECIMAL)
																		{	
//																			System.out.println(decimalValue);
//																			System.out.println("來了老弟:"+a+" "+b+" "+c+" "+d+" "+e+" "+f+" "+g+" "+h+" "+i+" "+j+" "+k+" "+l+" "+m+" "+n+" "+o);
																			ANSWER[0]=a;
																			ANSWER[1]=b;
																			ANSWER[2]=c;
																			ANSWER[3]=d;
																			ANSWER[4]=e;
																			ANSWER[5]=f;
																			ANSWER[6]=g;
																			ANSWER[7]=h;
																			ANSWER[8]=i;
																			ANSWER[9]=j;
																			ANSWER[10]=k;
																			ANSWER[11]=l;
																			ANSWER[12]=m;
																			ANSWER[13]=n;
																			ANSWER[14]=o;
																		}											
																}
															}
														}
													}
												}
											}
										}
									}
								}
							}
						}
					}
				}
			}
		}
	}
	public static void show()
	{
		int index=0;
		for(int i=0;i<15;i++)
		{
			if(ANSWER[i]!=0)
			{
				index=i;
				break;
			}
		}
		if(radixTransform.SYMBOL=='-')
		{
			System.out.print('-');
		}
		else
		{
			//DO NOTHING...
		}
		for(int i=index;i<ANSWER.length;i++)
		{
			if(ANSWER[i]==10)
			{
				System.out.print('A');
			}
			else if(ANSWER[i]==11)
			{
				System.out.print('B');
			}
			else if(ANSWER[i]==12)
			{
				System.out.print('C');
			}
			else if(ANSWER[i]==13)
			{
				System.out.print('D');
			}
			else if(ANSWER[i]==14)
			{
				System.out.print('E');
			}
			else if(ANSWER[i]==15)
			{
				System.out.print('F');
			}
			else
			{
				System.out.print(ANSWER[i]);
			}
			
		}
	}
	public static void main(String[] args)
	{
		char symbol=' ';
		@SuppressWarnings("resource")
		Scanner sc=new Scanner(System.in);
		String value=sc.nextLine();
		int decimal=Integer.parseInt(value);
		int radix=sc.nextInt();
		int decimalValue[]= new int[15];
		char[] charValue=value.toCharArray();
		if(charValue[0]=='-')
		{
			symbol='-';
			radixTransform.SYMBOL='-';
			for(int i=value.length()-1,j=14;i>0;i--,j--)
			{
				decimalValue[j]=charValue[i]-48;
			}
			
		}
		else
		{
			symbol=' ';
			radixTransform.SYMBOL=' ';
			for(int i=value.length()-1,j=14;i>=0;i--,j--)
			{
				decimalValue[j]=charValue[i]-48;
			}
		}
		radixTransform trans = new radixTransform(radix,symbol,decimal) ;
		trans.RadixTrans(decimalValue);
		trans.show();
	}
}

在辛辛苦苦寫完這點代碼之後,開始Debug了,首先拿二進制做了測試,發現沒有任何問題,一下就能得出正確答案。然鵝...,當我使用比二進制更大的轉換後,發現程序運行一直結束不了。第一反應是程序本身問題,在反覆糾察後,我並沒發現任何問題。於是我換了一個比二進制大一點點的計算,那就是3進制。當我輸入相應數值之後,程序還是一樣沒有停下來,經過三分鐘漫長的等待,終於出現了想要的結果,沒錯,三分鐘!!!僅僅計算了一個兩位數轉換成3進制!

emmm..很尷尬,不用說,這就是暴力破解的缺點,時間複雜度和空間複雜度相對較大,粗略的運算了一下,這個代碼運行二進制時,其計算量大概是10000多次就能出結果,而對於3進制來說,粗略計算下來,大概需要1400萬次才能得到正確結果 ,不敢往下想了....。我的CPU是志強x3470(弱雞一枚),如果你們無聊可以看看你們的電腦跑這個程序用3進制花多少時間....

因此,又要另尋它路了,這個接近200行的代碼報廢了。對於接下來的代碼,相對於上一個可能相差較大,因爲僅有14行,別問爲什麼。全靠jdk api文檔續命...

import java.util.Scanner;
public class radixTransform2 
{
	public static void main(String[] args)
	{
		Scanner sc=new Scanner(System.in);
		String value=sc.nextLine();
		int radix=sc.nextInt();
		String AfterTrans=Integer.toString(Integer.parseInt(value), radix);
		String Final=AfterTrans.toUpperCase();
		System.out.println(Final);
	}
}

運行起來還是嗖嗖帶風的啊!

全票通過!!!

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章