Android Resources$NotFoundException: String resource ID #0x1

今天写一个新界面,需要从其他界面通过intent传来参数,就先拿到之后通过TextView的setText显示来看看传参是否正确,写法:TextView.setText(arg) (arg是int型),然后就玩命报错 “android.content.res.Resources$NotFoundException: String resource ID #0x1”,一直不知道怎么回事,看过API才明白当调用setText()方法时如果传入int型是不会被当成内容而是resourceID来使用!R文件里当然不会有我的参数,所以报错!解决方法:TextView.setText(“” + arg)

Android FragmentTransaction 在不同版本下的奇怪问题

目前在做的一款APP,用到了一个布局块中的Fragment的切换,其中一个按钮按下后的事件如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
btnTranslate.setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View v)
{
/*当前界面不是翻译界面时才进行下列动作*/
if( MAIN_FRAGMENT_ID != currentFragmentId )
{
setChoosedBtnState(MAIN_FRAGMENT_ID);
FragmentManager fragmentManager = getFragmentManager();
if( null == fragmentTranslate )
fragmentTranslate = new MainUI();
hideCurrentFragment(fragmentTransaction);
fragmentTransaction.show(fragmentTranslate);
fragmentTransaction.add(R.id.fragment_content, fragmentTranslate, "MainUI");
fragmentTransaction.commit();
currentFragmentId = MAIN_FRAGMENT_ID;
}
}
});

fragmentTransaction.commit();currentFragmentId = MAIN_FRAGMENT_ID;}}});
1
2
hideCurrentFragment(fragmentTransaction);
fragmentTransaction.show(fragmentTranslate);

这两句本来是为了提高切换速度,并且保存用户产生的数据而选用隐藏/显示来代替replace(remove/add),运行时在Android 4.0的模拟器和我Android 4.1的手机上没有任何问题,效果也很好,但是当我把程序放在我的Android 4.4(Galaxy S5··貌似这个机型问题挺多···)时出现闪退!具体情形是,当我点击一个按钮创建了一个Fragment的实例时程序正常运行,但是当我再次点击已经创建过实例的界面按钮时就会闪退,一直不明白是怎么回事,查了API也没找到相关的说明。

搞了好久,最后看到

1
<pre name="code" class="java">fragmentTransaction.add(R.id.fragment_content, fragmentTranslate, "MainUI");

这句话,它作用就是把产生的Fragment实例加入到指定的布局块中,再联想我的问题,也就是在加入一次然后再次加入出现了问题,所以试着只在第一次创建Fragment实例时调用这条语句,果然问题解决!

修改后的代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
btnTranslate.setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View v)
{
/*当前界面不是翻译界面时才进行下列动作*/
if( MAIN_FRAGMENT_ID != currentFragmentId )
{
setChoosedBtnState(MAIN_FRAGMENT_ID);
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
if( null == fragmentTranslate )
{
fragmentTranslate = new MainUI();
fragmentTransaction.add(R.id.fragment_content, fragmentTranslate, "MainUI");
}
hideCurrentFragment(fragmentTransaction);
fragmentTransaction.show(fragmentTranslate);
fragmentTransaction.commit();
currentFragmentId = MAIN_FRAGMENT_ID;
}
}
});

Android Error: No resource found ···

关于 android:id=”@+id/” 和 android:id=”@id/” 的问题

本以为自己已经理解了这两个,无非就是第一次创建id时用+id/呗
但是没想到这里创建顺序是严格按照代码顺序来的,如:在RelativeLayout中

1
2
3
4
5
6
7
<RelativeLayout
...

<Widget1 android:layout_above="@id/widget_2" .../>
<Widget2 android:id="@+id/widget_2" ... />

<RelativeLayout/>

这样写会报错,大致说是Widget1找不到widget_2!!!!

原来需要在Widget1中这么写:android:layout_above=”@+id/widget_2″
也就是在第一次遇到这个id时就创建它,放心,这个id还是Widget2的,只是先被Widget1拿去创建并引用了而已

【PHP学习】move_uploaded_file() 使用注意

今天刚弄好WAMP,端口问题焦头烂额一上午,最后停止IIS服务就好了。。。

看PHP基本的部分,在用到 move_uploaded_file()时一直是错误,说是无法把文件从临时路径移动到指定路径下,最后发现指定路径不存在。。。就是最后的upload目录没有创建,心里还想着它会自动创建这个目录呢,真是傻了。。。

(代码是W3SCHOOL上的例子,稍有改动)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
<?php
if( $_FILES["file"]["type"] == "text/plain" && $_FILES["file"]["type"] < 20000 )
{
if ($_FILES["file"]["error"] > 0)
{
echo "Error: " . $_FILES["file"]["error"] . "<br />";
}
else
{
$oldPath = $_FILES["file"]["tmp_name"];
$newPath = "D:\\WAMP Server\\wamp\\tmp\\upload\\" . $_FILES["file"]["name"];

echo "Upload: " . $_FILES["file"]["name"] . "<br />";
echo "Type: " . $_FILES["file"]["type"] . "<br />";
echo "Size: " . ($_FILES["file"]["size"] / 1024) . " Kb<br />";
echo "Stored in: $oldPath temporarily!<br />";

if( file_exists($newPath) )
{
echo "$newPath already exists!";
}
else
{
move_uploaded_file($oldPath, $newPath);
echo "Stored in: $newPath !";
}
}
}
else
{
echo "Invalid File!";
}
?>

Java 多线程学习中遇到的一个有趣的问题

今天随便写了一个线程之间相互调度的程序,代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
class First extends Thread
{
public First()
{
start();
}

synchronized public void run()
{
try
{
wait();
}
catch(InterruptedException e)
{
e.printStackTrace();
}
try
{
sleep(2000);
}
catch(InterruptedException e)
{
e.printStackTrace();
}
System.out.println("hello world~");
}
}

class Second extends Thread
{
First first;
public Second(First first)
{
this.first = first;
start();
}

synchronized public void run()
{
try
{
wait();
}
catch (InterruptedException e1)
{
e1.printStackTrace();
}
synchronized( first )
{
try
{
sleep(2000);
System.out.println("I'm faster than first~");
}
catch(InterruptedException e)
{
e.printStackTrace();
}
first.notifyAll();
}
}
}

public class Main
{
public static void main(String[] args) throws InterruptedException
{
First first = new First();
Second second = new Second(first);
synchronized( second )
{
System.out.println("I'm faster than second~");
second.notifyAll();
}
}
}

本以为输出会很顺畅,但是出现的问题是,只输出了一行:I’m faster than second~

程序就一直处于无响应状态,纠结了好久终于想明白是这么一回事:在main函数中,对second.notifyAll()的调用早于second中的wait()调用(因为是多线程并行,故函数响应时间与代码先后顺序无关),这样先唤醒了second,紧接着second才开始wait,因此就处于无响应状态。

改进方法:只要在second.notifyAll()调用之前空出一点时间先让second的wait调用开始即可,事实上,这段时间如此之短以至于在我电脑上只需要在之前加一行输出语句即可。为了保险起见,还是多加了个sleep,改进后代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
class First extends Thread
{
public First()
{
start();
}

synchronized public void run()
{
try
{
wait();
}
catch(InterruptedException e)
{
e.printStackTrace();
}
try
{
sleep(2000);
}
catch(InterruptedException e)
{
e.printStackTrace();
}
System.out.println("hello world~");
}
}

class Second extends Thread
{
First first;
public Second(First first)
{
this.first = first;
start();
}

synchronized public void run()
{
try
{
wait();
}
catch (InterruptedException e1)
{
e1.printStackTrace();
}
synchronized( first )
{
try
{
sleep(2000);
System.out.println("I'm faster than first~");
}
catch(InterruptedException e)
{
e.printStackTrace();
}
first.notifyAll();
}
}
}

public class Main
{
public static void main(String[] args) throws InterruptedException
{
First first = new First();
Second second = new Second(first);
System.out.println("wating for all threads prepared~");
Thread.sleep(2000);
synchronized( second )
{
System.out.println("I'm faster than second~");
second.notifyAll();
}
}
}

输出结果:

1
2
3
4
wating for all threads prepared~
I’m faster than second~
I’m faster than first~
hello world~

文件夹遍历 Java 版

Java下的File类(文件类,其实感觉文件类有点误导性,用“文件路径”会好一点)有list方法,会返回指定路径下所有文件和目录,用这个方法以及简单的递归可以写出一个简陋的文件遍历程序

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;

public class test_for_team_study_2
{
public static void traverse(String name, FileWriter wt) throws IOException
{
wt.write(name + "\r\n");
File path = new File(name);
String[] list = path.list();
if( null == list )
return ;
for(int i = 0; i < list.length; i ++)
if( -1 == list[i].indexOf(".") )
traverse(name + "/" + list[i], wt);
}

public static void main(String[] args) throws IOException
{
FileWriter wt = new FileWriter("C:/Users/Administrator/Desktop/file in D.out");
String name = "D:/";
File path = new File(name);
String[] list = path.list();
for(int i = 0; i < list.length; i ++)
{
wt.write("now is the file#:" + i + "\r\n==========================\r\n");
traverse(name + "/" + list[i], wt);
wt.write("\r\n\r\n\r\n");
}
wt.flush();
wt.close();
System.out.println("finished!");
}
}

JAVA 设置 JTable 表格的可编辑性

有时候,我们需要设置JTable表格某些行某些列不可编辑以保证数据准确,用DefaultTableModel初始化的话,需要重写它的public boolean isCellEditable(int, int)方法,写法简单呈现如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
DefaultTableModel myModel = new DefaultTableModel(dataOfOrder, headOfOrder)	//实例化表格模式
{
/**
*
*/
private static final long serialVersionUID = 1L;

public boolean isCellEditable(int rowIndex, int columnIndex) //重写方法改编可编辑性
{
if( columnIndex == getColumnCount() - 1 )
return true;
return false;
}
};

上述写法是设置只有表格的最后一列可编辑,其他列不可编辑。有了rowIndex和columnIndex这两个参数,可以随意的设置可编辑范围。

注意要达到目的,定义另一个类继承DefaultTableModel,之后在类中重写方法是不可行的!

Java 窗体中按钮布局问题

在Java窗体中,有时需要对按钮的设置进行布局,这时使用GridLayout(x, y)会很方便,意思是把窗口划分为x行y列的小格子,在add的时候就是一行一行的填充,这样可以是按钮得到标准化布局

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.Toolkit;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class test_for_blog extends JFrame
{
/**
*
*/
private static final long serialVersionUID = 5136083409273453255L;

private static int JFwidth = 450;
private static int JFheight = 350;

JPanel panel = null;

JButton btnAdd = null;
JButton btnDelete = null;

public test_for_blog()
{
super("按钮添加测试");

panel = new JPanel();

btnAdd = new JButton("Add");
btnDelete = new JButton("Delete");

panel.setLayout( new GridLayout(1, 2) );
panel.add(btnAdd);
panel.add(btnDelete);
this.getContentPane().add(panel, BorderLayout.SOUTH);
}

public static void main(String[] args)
{
test_for_blog test = new test_for_blog();
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); //获取显示屏尺寸
test.setBounds((screenSize.width - JFwidth) / 2, (screenSize.height - JFheight) / 2, JFwidth, JFheight); //使程序窗口居中
test.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //窗口设为可关闭
test.setResizable(false); //窗口设为不可调节大小
test.setVisible(true); //窗口设为可见
}
}

POJ 3255 Roadblocks (次短路问题)

解法有很多奇葩的地方,比如可以到达终点再跳回去再跳回来(比如有两个点)。。。。反正就是不能有最短路,不过没关系,算法都能给出正确结果

思想:和求最短路上的点套路一样,spfa先正着求一次,再反着求一次最短路,然后枚举每条边<i,j>找dist_zheng[i] + len<i,j> + dist_fan[j]的第二小值即可!注意不能用邻接矩阵,那样会MLE,应该用邻接表

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
/*
poj 3255
3808K 266MS
*/

#include<cstdio>
#include<cstring>
#include<queue>
#include<iostream>

#define MAXN 200005
#define MAX_INT 2147483647

using namespace std;

int last[5005], dist_1[5005], dist_2[5005], n, m, gra[5005][5005];
bool mark[MAXN];

struct node
{
int u;
int v;
int w;
int next;
node()
{
u = v = w = next = 0;
}
}edge[MAXN];

void spfa( int dist[5005], int s )
{
queue<int>myQueue;
dist[s] = 0;
memset(mark, false, sizeof(mark));
mark[s] = true;
myQueue.push(s);
while( !myQueue.empty() )
{
int x = myQueue.front();
myQueue.pop();
mark[x] = false;
int t = last[x];
while( t )
{
if( dist[ edge[t].v ] > dist[x] + edge[t].w )
{
dist[ edge[t].v ] = dist[x] + edge[t].w;
if( !mark[ edge[t].v ] )
myQueue.push( edge[t].v );
}
t = edge[t].next;
}
}
}

int main()
{
cin >> n >> m;
for(int i = 1;i <= m;i ++)
{
int a, b, c;
scanf("%d %d %d", &a, &b, &c);
edge[i].u = edge[i + m].v = a;
edge[i].v = edge[i + m].u = b;
edge[i].w = edge[i + m].w = c;
edge[i].next = last[a];
last[a] = i;
edge[i + m].next = last[b];
last[b] = i + m;
}
memset( dist_1, 1, sizeof(dist_1) );
spfa( dist_1, 1 );
memset( dist_2, 1, sizeof(dist_2) );
spfa( dist_2, n );
int ans = MAX_INT, tmp = MAX_INT;
for(int i = 1;i <= n;i ++)
{
int t = last[i];
while( t )
{
if( dist_1[i] + dist_2[ edge[t].v ] + edge[t].w < tmp )
{
ans = tmp;
tmp = dist_1[i] + dist_2[ edge[t].v ] + edge[t].w;
}
else if( dist_1[i] + dist_2[ edge[t].v ] + edge[t].w < ans
&& dist_1[i] + dist_2[ edge[t].v ] + edge[t].w != tmp )
ans = dist_1[i] + dist_2[ edge[t].v ] + edge[t].w;
t = edge[t].next;
}
}
cout << ans << endl;
return 0;
}

POJ 3093 Margaritas on the River Walk(0-1背包变形)

这题目的思路很巧妙,什么情况下剩下的所有物品都放不下呢?就是当前剩余物品中最小的那个也放不下。所以,先把物品按照容量从小到大排序,依次枚举当前背包为放不下的最小物品的情况。

对于当前物品i,必有1到i-1的所有物品都放进去,这时候比i大的物品谁放谁不放是不确定的。转换成0-1背包问题:把前i-1个物品都放进去以后,得到空间为tsum – sum[i-1](前缀和)的包,只要从第i+1到第n个物品中拿出一个方案填充这个包使得剩余体积小于第i个物品的体积就可以了,把总方案数累加就是结果!

注意特殊情况:当排序后最小的物品也无法放入时,直接返回0,因为dp[0]初始化为1,

代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
/*
poj 3093
232K 0MS
*/
#include<cstdio>
#include<algorithm>
#include<iostream>

#define MAXN 1005

using namespace std;

int n, m, wei[35], dp[MAXN], sum[MAXN];

__int64 Bag()
{
memset(sum, 0, sizeof(sum));
sort( wei + 1, wei + n + 1 );
if(wei[1] > m) //因为很可能有最小的也放不下这种情况,而dp【0】是初始化为1的,会输出1
return 0;
for(int i = 1;i <= n;i ++)
sum[i] = sum[i-1] + wei[i];
__int64 ans = 0;
for(int i = 1;i <= n;i ++)
{
if(sum[i - 1] > m)
break;
memset(dp, 0, sizeof(dp));
dp[sum[i-1]] = 1;
for(int j = i + 1;j <= n;j ++)
for(int k = m; k >= sum[i - 1] + wei[j]; k --)
dp[k] += dp[k - wei[j]];

for(int j = m - wei[i] + 1;j <= m;j ++)
ans += dp[j];
}
return ans;
}

int main()
{
int Cases;
cin>>Cases;
for(int cnt = 1; cnt <= Cases; cnt ++)
{
cin >> n >> m;
for(int i = 1;i <= n;i ++)
cin>> wei[i];
cout << cnt << " " << Bag() <<endl;
}
return 0;
}