公鏈,顧名思義就是具有很大的包容性和公平性的,哪個(gè)公鏈項(xiàng)目在這兩點(diǎn)上做得越好就越能突出。目前很多共公鏈為了交易的速度而犧牲了公平性,不看好。有個(gè)項(xiàng)目叫梵塔網(wǎng)絡(luò)的,他們的DSC技術(shù)就聲稱能兼具安全性、民主化和公平化,值得長期關(guān)注,不過他們代碼年底才會(huì)開源,進(jìn)度需要加快了
目前創(chuàng)新互聯(lián)已為上1000家的企業(yè)提供了網(wǎng)站建設(shè)、域名、網(wǎng)站空間、網(wǎng)站改版維護(hù)、企業(yè)網(wǎng)站設(shè)計(jì)、翼城網(wǎng)站維護(hù)等服務(wù),公司將堅(jiān)持客戶導(dǎo)向、應(yīng)用為本的策略,正道將秉承"和諧、參與、激情"的文化,與客戶和合作伙伴齊心協(xié)力一起成長,共同發(fā)展。
這個(gè)是給你看的注釋版:
import java.util.LinkedList;
import java.util.Scanner;
public class Test6 {
int[][] array;
int m = 0, n = 0;
LinkedListString quere = new LinkedListString();
public Test6() {
quere.add("r");
quere.add("d");
quere.add("l");
quere.add("u");
}//定義了一個(gè)List里面裝了["u","l","d","r"]四個(gè)String類型的東西
//從后面的應(yīng)用來,"u"代表的是up,這個(gè)程序做的是根據(jù)給定數(shù)字X,構(gòu)建
//出一個(gè)一維二維長均為X的數(shù)組,數(shù)組中以順時(shí)針的方式用數(shù)字1到X*X進(jìn)行填充
//可以想象成蛇行的往里面盤繞.
//這里的"u"也就是從下往上填充的意思了,其他的就不用我說了吧,"l"=left,"d"=down,"r"=right
public void printTest6(int N) {
array = new int[N][N];
for (int i = 1; i = N * N; i++) {
array[m][n] = i;
indexControl(quere, N);
}//數(shù)組賦值執(zhí)行完畢
//接下來打印出數(shù)組
for (int i = 0; i N; i++) { //N 行
for (int j = 0; j N; j++) { //N 列
System.out.print(array[i][j] + "\t");//輸出二維數(shù)組 "\t"是一個(gè)tab鍵符號(hào)
}
//每打完一組二維的數(shù)據(jù),加換行
System.out.println();//換行
System.out.println();//換行
}
}
private void indexControl(LinkedListString quere, int N) {
String method = quere.peek();
//調(diào)用peek()返回鏈表的頭部節(jié)點(diǎn),對(duì)于初始狀態(tài)["u","l","d","r"]來說,返回的是"r"
if (method.equals("r")) {
//如果頭部節(jié)點(diǎn)是"r",換句話說具體填充的時(shí)候就是從左往右先開始填充.
//這時(shí)候的填充操作,對(duì)于二維數(shù)組來說自然就是固定第一維不變,第二維遞增了.
n++;//固定第一維不變,第二維做遞增操作
if ((n == N - 1) || array[m][n + 1] != 0) {
//這種操作的停止條件是走到了數(shù)組的邊緣,也就是n == N - 1,因?yàn)閚是從0開始發(fā)番
//另一種終止條件就是找到了一個(gè)已經(jīng)被賦值過了的位置.
quere.add(quere.poll());
//條件終止之后就應(yīng)該換方向了.調(diào)用poll方法獲得頭節(jié)點(diǎn),初始狀態(tài)就是"r",
//然后poll方法還會(huì)把"r"從原始鏈表中刪除,因此調(diào)用完poll之后原始鏈表應(yīng)該變成了
//["u","l","d"],然后在調(diào)用add方法,把"r"追加到尾部,此時(shí)鏈表就變成["r","u","l","d"]
//下一步再取頭就是"d"了,也就是開始往下走.
}
} else if (method.equals("d")) {
//這里,如果頭節(jié)點(diǎn)是"d",也就是從上往下開始賦值了,
//這時(shí)候應(yīng)該是保持第二維坐標(biāo)不變,第一維坐標(biāo)遞增.
m++;//固定第二維不變,第一維做遞增操作
if ((m == N - 1) || array[m + 1][n] != 0) {
//這種操作的停止條件是走到了數(shù)組的邊緣,也就是m == N - 1,因?yàn)閙是從0開始發(fā)番
//另一種終止條件就是找到了一個(gè)已經(jīng)被賦值過了的位置.
quere.add(quere.poll());
//條件終止開始換方向,把"d"放在鏈表的尾部,"l"成了頭
}
} else if (method.equals("l")) {
//這里,如果頭節(jié)點(diǎn)是"l",也就是從右往左開始賦值了,
//這時(shí)候應(yīng)該是保持第一維坐標(biāo)不變,第二維坐標(biāo)遞減.
n--;//固定第一維不變,第二維做遞減操
if ((n == 0) || array[m][n - 1] != 0) {
//這種操作的停止條件是走到了數(shù)組的邊緣,也就是n == 0.
//另一種終止條件就是找到了一個(gè)已經(jīng)被賦值過了的位置.
quere.add(quere.poll());
//條件終止開始換方向,把"l"放在鏈表的尾部,"u"成了頭
}
} else {
//這里,如果頭節(jié)點(diǎn)是"u",也就是從下往上開始賦值了,
//這時(shí)候應(yīng)該是保持第二維坐標(biāo)不變,第一維坐標(biāo)遞減.
m--;//固定第二維不變,第一維做遞減操
if (array[m - 1][n] != 0) {
//終止條件就是找到了一個(gè)已經(jīng)被賦值過了的位置.這里不把數(shù)組邊界作為判斷條件是因?yàn)?
//可以保證在執(zhí)行到這個(gè)部分的時(shí)候,數(shù)組的上部邊界已經(jīng)全部有值.
quere.add(quere.poll());
//條件終止開始換方向,把"u"放在鏈表的尾部,"r"成了頭
}
}
}
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);//將輸入流交給scan對(duì)象
System.out.println("請(qǐng)輸入矩形的大?。?);
int num = scan.nextInt();//scan對(duì)象獲得從控制臺(tái)輸入的東西
new Test6().printTest6(num);//根據(jù)輸入的數(shù)值構(gòu)建數(shù)組
}
}
另外,程序不夠嚴(yán)密,有障害,輸入不是大于1的正整數(shù)就會(huì)掛,下面是修正版:
package Date0906.Date0906_Test6;
import java.util.LinkedList;
import java.util.Scanner;
public class Test6_Up {
int[][] array;
int m = 0, n = 0;
LinkedListString quere = new LinkedListString();
public Test6_Up() {
quere.add("r");
quere.add("d");
quere.add("l");
quere.add("u");
}
public void printTest6(int N) {
array = new int[N][N];
for (int i = 1; i = N * N; i++) {
array[m][n] = i;
indexControl(quere, N);
}
for (int i = 0; i N; i++) { //N 行
for (int j = 0; j N; j++) { //N 列
System.out.print(array[i][j] + "\t");//輸出二維數(shù)組
}
System.out.println();//換行
System.out.println();//換行
}
}
private void indexControl(LinkedListString quere, int N) {
String method = quere.peek();
if (method.equals("r")) {//從左往右寫二維數(shù)組
n++;
if ((n == N - 1) || ( N !=1 array[m][n + 1] != 0 )) {
//如果N為1或者檢索到邊界,或者檢索到已經(jīng)被賦值的點(diǎn),重置鏈表,換賦值方向
quere.add(quere.poll());
}
} else if (method.equals("d")) {//從上往下寫二維數(shù)組
m++;
if ((m == N - 1) || ( N !=1 array[m + 1][n] != 0 )) {
//如果N為1或者檢索到邊界,或者檢索到已經(jīng)被賦值的點(diǎn),重置鏈表,換賦值方向
quere.add(quere.poll());
}
} else if (method.equals("l")) {//從右往左寫二維數(shù)組
n--;
if ((n == 0) || ( N !=1 array[m][n - 1] != 0 )) {
//如果N為1或者檢索到邊界,或者檢索到已經(jīng)被賦值的點(diǎn),重置鏈表,換賦值方向
quere.add(quere.poll());
}
} else {//從下往上寫二維數(shù)組
m--;
if (N !=1 array[m - 1][n] != 0) {
//如果N為1或者檢索到已經(jīng)被賦值的點(diǎn),重置鏈表,換賦值方向
quere.add(quere.poll());
}
}
}
public static void main(String[] args) {
Scanner scan = null;
System.out.println("請(qǐng)輸入矩形的大小:");
int num = 0;
while ( true ) {
scan = new Scanner(System.in);
//用try捕獲異常,當(dāng)輸整數(shù)以外的內(nèi)容時(shí)給提示和再次輸入的機(jī)會(huì).
try {
num = scan.nextInt();
} catch (Exception e) {
System.out.println("請(qǐng)輸入正整數(shù)");
continue;
}
//如果發(fā)現(xiàn)輸入的數(shù)字是非正數(shù),則要求再次輸入
if ( 0 = num ) {
System.out.println("請(qǐng)輸入正整數(shù)");
continue;
}
break;
}
new Test6_Up().printTest6(num);
}
}
import java.util.*; public class Main { public static void main(String[] args) { Scanner in = new Scanner(System.in); // in.hasNextInt() 用來判斷是否還能讀取int while(in.hasNextInt()) { int n = in.nextInt(); int u = in.nextInt(); int d = in.nextInt(); if(n == 0) System.exit(1); int sum = 0; int time = 0; while(true) { sum += u; time ++; if(sum = n) break; sum -= d; time ++; } System.out.println(time); } } }
一樓的說的夠全面了,不過稍有誤解.
再來表示抱歉,我對(duì)編程語言中的中文名詞非常不了解,所以如果以下的回復(fù)對(duì)你的閱讀或者理解造成困難,請(qǐng)見諒.
1.首先,要明白這個(gè)問題的答案,需要了解call?(pass)?by?value?和?call?(pass)?by?reference?的區(qū)別.簡(jiǎn)單來說:
call?by?value通常是復(fù)制這個(gè)parameter的值去另外一塊內(nèi)存里,然后傳給function,?所以在method/function里邊對(duì)這個(gè)變量的所有變更,實(shí)際上都是對(duì)復(fù)制過來的鏡像進(jìn)行操作,不會(huì)對(duì)原本的variable有任何影響.
call?by?reference是將parameter的reference傳給function,簡(jiǎn)單點(diǎn)理解就是直接把variable傳給function.所以說這個(gè)variable的值是可以被function改變的.這個(gè)用法在c/c++中非常常見,用法是variable_name.
2.再來,在Java里邊,你可以很簡(jiǎn)單的理解為:?Java中只有call?by?value,?也就是說,所以所有傳給function的parameter本身都不會(huì)被改變.?(這是最簡(jiǎn)單直白的理解,當(dāng)然也有另一種常從sun的人那邊聽到的說法:Java是call?by?value?+?call?by?reference?by?value)
3.那么現(xiàn)在的問題就是為什么第二個(gè)結(jié)果是2了.?首先說一下sun官方的解釋:?對(duì)于reference?type在作為parameter/argument的時(shí)候,也是call?by?value,?但是在你擁有足夠權(quán)限時(shí)(比方說那個(gè)變量是public的,?不是final的等等各種符合的情況),可以修改這個(gè)object中fields的值(也就是屬于這個(gè)object(嚴(yán)謹(jǐn)點(diǎn)講是an?instance?of?the?object)?內(nèi)部的變量,?在你的例子中,?ko?里邊的?a?就是一個(gè)field,?所以u(píng)pdate(ko)會(huì)使ko.a變成2).
4.如果你是一個(gè)有過c/c++學(xué)習(xí)經(jīng)驗(yàn)的人或者你以上的解釋很難理解,以下這種說法或許更適合你?(當(dāng)然了,這只是大多包括我在內(nèi)有c經(jīng)驗(yàn)的人的一種理解方式)
這里可以引入一個(gè)新的概念,pointer.?這是一種比較特殊的變量,它內(nèi)部所儲(chǔ)存的東西,其實(shí)只是另外一個(gè)變量的內(nèi)存地址.?如果對(duì)內(nèi)存沒有概念,你可以把它簡(jiǎn)單理解為是風(fēng)箏的線軸,雖然看它本身看不出什么端倪,但是順著摸過去總會(huì)找到風(fēng)箏,看到它是什么樣子.?以pointer方式理解Java的人,通常會(huì)說:?Type?variable?=?new?Type();?這個(gè)過程中,最后生成的這個(gè)variable其實(shí)就是一個(gè)pointer,而不是instance本身.
在Java中,?有c/c++經(jīng)驗(yàn)的人通常認(rèn)為Java是call?by?value.同時(shí),當(dāng)一個(gè)變量用在儲(chǔ)存reference?type的時(shí)候,實(shí)際上儲(chǔ)存的是它的pointer,這也一樣可以解釋為什么ko.a會(huì)有2這個(gè)結(jié)果,因?yàn)殡m然pointer被傳到function里邊時(shí),本身是call?by?value,無法被改變.但這并不影響function本身對(duì)這個(gè)pointer指向的object的內(nèi)容做任何改變.?當(dāng)然,再次聲明,這只是一種幫助有c/c++經(jīng)驗(yàn)的人理解的方法.?Sun本身嚴(yán)正聲明Java里邊沒有pointer這個(gè)東西的存在.
5.?再來解釋一下為什么說樓上所說的(或者說樓上引用的)理解略有偏差.
引用"我們上面剛學(xué)習(xí)了JAVA的數(shù)據(jù)類型,則有:值類型就是按值傳遞的,而引用類型是按引用傳遞的"?這句話很明顯的有兩點(diǎn)錯(cuò)誤.?第一點(diǎn),如果我上面所說的,Java是沒有call?by?reference的.
第二點(diǎn),暫且假設(shè)Java里邊是有call?by?reference的,?這句話依然不成立.
Java中的變量有兩種類型:?primitive?types?和?reference?type.
primitive?type包括byte,?short,?int,?long,?char,?boolean,?float和double.
而這8種之外的所有的,都是reference?type.
下面是一段對(duì)你的貼上來的code的一點(diǎn)延伸,希望可以幫助你更好的理解Java中的argument?/?parameter到底是如何運(yùn)作的.
public?class?Test?{
public?static?void?main(String[]?args)?{
int?a?=?1;
Koo?koo?=?new?Koo();
Object?o?=?new?Integer(1);
Koo?newKoo?=?new?Koo();
update(a);
update(koo);
update(o);
update(newKoo);
newUpdate(newKoo);
System.out.println(a);
System.out.println(koo.a);
System.out.println(o);
System.out.println(newKoo.a);
}
static?void?update(int?a)?{
a++;
}
static?void?update(Koo?koo)?{
koo.a++;
}
static?void?update(Object?o)?{
o?=?(int)?(Integer.parseInt(o.toString())?+?1);
}
static?void?newUpdate(Koo?koo)?{
koo?=?new?Koo();
}
}
class?Koo?{
int?a?=?1;
}
/*
o?=?(int)?(Integer.parseInt(o.toString())?+?1);?這一行中的(int)純粹是多余的,是否有這個(gè)casting對(duì)code本身沒有任何影響.?如果你高興也可以用
o?=?new?Integer(Integer.parseInt(o.toString())?+?1);
或者干脆
o?=?Integer.parseInt(o.toString())?+?1;
*/
以上這些code運(yùn)行之后會(huì)得到1?2?1?2的結(jié)果.?后面兩個(gè)結(jié)果可以很好的說明,?即使對(duì)objects?(reference?type?variables)?來看,?Java所應(yīng)用的也并不是call?by?reference.?否則的話,以上code運(yùn)行結(jié)果應(yīng)該是1?2?2?1
希望你可以真正理解這個(gè)新的例子中,產(chǎn)生1212這個(gè)結(jié)果的原因,從而對(duì)Java中的arguments有一個(gè)系統(tǒng)全面的認(rèn)識(shí).
圖片是相關(guān)資料的鏈接,知道里貌似不能加網(wǎng)址
javax.crypto.Cipher類提供加密和解密功能,該類是JCE框架的核心。
一,與所有的引擎類一樣,可以通過調(diào)用Cipher類中的getInstance靜態(tài)工廠方法得到Cipher對(duì)象。
public static Cipher getInstance(String transformation);
public static Cipher getInstance(String transformation,String provider);
參數(shù)transformation是一個(gè)字符串,它描述了由指定輸入產(chǎn)生輸出所進(jìn)行的操作或操作集合。
參數(shù)transformation總是包含密碼學(xué)算法名稱,比如DES,也可以在后面包含模式和填充方式。
參數(shù)transformation可以是下列兩種形式之一:
“algorithm/mode/padding”
“algorithm”
例如下面的例子就是有效的transformation形式:
"DES/CBC/PKCS5Padding"
"DES"
如 果沒有指定模式或填充方式,就使用特定提供者指定的默認(rèn)模式或默認(rèn)填充方式。例如,SunJCE提供者使用ECB作為DES、DES-EDE和 Blowfish等Cipher的默認(rèn)模式,并使用PKCS5Padding作為它們默認(rèn)的填充方案。這意味著在SunJCE提供者中,下列形式的聲明是 等價(jià)的:Cipher c1=Cipher.getInstance("DES/ECB/PKCS5Padding");
Cipher c1=Cipher.getInstance("DES");
當(dāng) 以流加密方式請(qǐng)求以塊劃分的cipher時(shí),可以在模式名后面跟上一次運(yùn)算需要操作的bit數(shù)目,例如采用"DES/CFB8/NoPadding"和 "DES/OFB32/PKCS5Padding"形式的transformation參數(shù)。如果沒有指定數(shù)目,則使用提供者指定的默認(rèn)值(例如 SunJCE提供者使用的默認(rèn)值是64bit)。
getInstance工廠方法返回的對(duì)象沒有進(jìn)行初始化,因此在使用前必須進(jìn)行初始化。
通過getInstance得到的Cipher對(duì)象必須使用下列四個(gè)模式之一進(jìn)行初始化,這四個(gè)模式在Cipher類中被定義為final integer常數(shù),我們可以使用符號(hào)名來引用這些模式:
ENCRYPT_MODE,加密數(shù)據(jù)
DECRYPT_MODE,解密數(shù)據(jù)
WRAP_MODE,將一個(gè)Key封裝成字節(jié),可以用來進(jìn)行安全傳輸
UNWRAP_MODE,將前述已封裝的密鑰解開成java.security.Key對(duì)象
每個(gè)Cipher初始化方法使用一個(gè)模式參數(shù)opmod,并用此模式初始化Cipher對(duì)象。此外還有其他參數(shù),包括密鑰key、包含密鑰的證書certificate、算法參數(shù)params和隨機(jī)源random。
我們可以調(diào)用以下的init方法之一來初始化Cipher對(duì)象:
public void init(int opmod,Key key);
public void init(int opmod,Certificate certificate);
public void init(int opmod,Key key,SecureRandom random);
public void init(int opmod,Certificate certificate,SecureRandom random);
public void init(int opmod,Key key,AlgorithmParameterSpec params);
public void init(int opmod,Key key,AlgorithmParameterSpec params,SecureRandom random);
public void init(int opmod,Key key,AlgorithmParameters params);
public void init(int opmod,Key key,AlgorithmParameters params,SecureRandom random);
必須指出的是,加密和解密必須使用相同的參數(shù)。當(dāng)Cipher對(duì)象被初始化時(shí),它將失去以前得到的所有狀態(tài)。即,初始化Cipher對(duì)象與新建一個(gè)Cipher實(shí)例然后將它初始化是等價(jià)的。
二,可以調(diào)用以下的doFinal()方法之一完成單步的加密或解密數(shù)據(jù):
public byte[] doFinal(byte[] input);
public byte[] doFinal(byte[] input,int inputOffset,int inputLen);
public int doFinal(byte[] input,int inputOffset,int inputLen,byte[] output);
public int doFinal(byte[] input,int inputOffset,int inputLen,byte[] output,int outputOffset);
在多步加密或解密數(shù)據(jù)時(shí),首先需要一次或多次調(diào)用update方法,用以提供加密或解密的所有數(shù)據(jù):
public byte[] update(byte[] input);
public byte[] update(byte[] input,int inputOffset,int inputLen);
public int update(byte[] input,int inputOffset,int inputLen,byte[] output);
public int update(byte[] input,int inputOffset,int inputLen,byte[] output,int outputOffset);
如果還有輸入數(shù)據(jù),多步操作可以使用前面提到的doFinal方法之一結(jié)束。如果沒有數(shù)據(jù),多步操作可以使用下面的doFinal方法之一結(jié)束:
public byte[] doFinal();
public int doFinal(byte[] output,int outputOffset);
如果在transformation參數(shù)部分指定了padding或unpadding方式,則所有的doFinal方法都要注意所用的padding或unpadding方式。
調(diào)用doFinal方法將會(huì)重置Cipher對(duì)象到使用init進(jìn)行初始化時(shí)的狀態(tài),就是說,Cipher對(duì)象被重置,使得可以進(jìn)行更多數(shù)據(jù)的加密或解密,至于這兩種模式,可以在調(diào)用init時(shí)進(jìn)行指定。
三,包裹wrap密鑰必須先使用WRAP_MODE初始化Cipher對(duì)象,然后調(diào)用以下方法:
public final byte[] wrap(Key key);
如果將調(diào)用wrap方法的結(jié)果(wrap后的密鑰字節(jié))提供給解包裹unwrap的人使用,必須給接收者發(fā)送以下額外信息:
(1)密鑰算法名稱:
密鑰算法名稱可以調(diào)用Key接口提供的getAlgorithm方法得到:
public String getAlgorithm();
(2)被包裹密鑰的類型(Cipher.SECRET_KEY,Cipher.PRIVATE_KEY,Cipher.PUBLIC_KEY)
sourcelink: ;nid=41716order=tid=
為了對(duì)調(diào)用wrap方法返回的字節(jié)進(jìn)行解包,必須先使用UNWRAP_MODE模式初始化Cipher對(duì)象,然后調(diào)用以下方法 :
public final Key unwrap(byte[] wrappedKey,String wrappedKeyAlgorithm,int wrappedKeyType));
其 中,參數(shù)wrappedKey是調(diào)用wrap方法返回的字節(jié),參數(shù)wrappedKeyAlgorithm是用來包裹密鑰的算法,參數(shù) wrappedKeyType是被包裹密鑰的類型,該類型必須是Cipher.SECRET_KEY,Cipher.PRIVATE_KEY, Cipher.PUBLIC_KEY三者之一。
四,SunJCE提供者實(shí)現(xiàn)的cipher算法使用如下參數(shù):
(1)采用CBC、CFB、OFB、PCBC模式的DES、DES-EDE和Blowfish算法。,它們使用初始化向量IV作為參數(shù)??梢允褂胘avax.crypto.spec.IvParameterSpec類并使用給定的IV參數(shù)來初始化Cipher對(duì)象。
(2)PBEWithMD5AndDES使用的參數(shù)是一個(gè)由鹽值和迭代次數(shù)組成的參數(shù)集合。可以使用javax.crypto.spec.PBEParameterSpec類并利用給定鹽值和迭代次數(shù)來初始化Cipher對(duì)象。
注意:如果使用SealedObject類,就不必為解密運(yùn)算參數(shù)的傳遞和保存擔(dān)心。這個(gè)類在加密對(duì)象內(nèi)容中附帶了密封和加密的參數(shù),可以使用相同的參數(shù)對(duì)其進(jìn)行解封和解密。
Cipher 中的某些update和doFinal方法允許調(diào)用者指定加密或解密數(shù)據(jù)的輸出緩存。此時(shí),保證指定的緩存足夠大以容納加密或解密運(yùn)算的結(jié)果是非常重要 的